summaryrefslogtreecommitdiff
path: root/deps/v8/test/cctest
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/cctest')
-rw-r--r--deps/v8/test/cctest/BUILD.gn24
-rw-r--r--deps/v8/test/cctest/asmjs/OWNERS1
-rw-r--r--deps/v8/test/cctest/asmjs/test-asm-typer.cc76
-rw-r--r--deps/v8/test/cctest/cctest.gyp39
-rw-r--r--deps/v8/test/cctest/cctest.h15
-rw-r--r--deps/v8/test/cctest/cctest.status100
-rw-r--r--deps/v8/test/cctest/compiler/code-assembler-tester.h57
-rw-r--r--deps/v8/test/cctest/compiler/function-tester.cc12
-rw-r--r--deps/v8/test/cctest/compiler/function-tester.h3
-rw-r--r--deps/v8/test/cctest/compiler/test-code-assembler.cc312
-rw-r--r--deps/v8/test/cctest/compiler/test-js-context-specialization.cc472
-rw-r--r--deps/v8/test/cctest/compiler/test-js-typed-lowering.cc9
-rw-r--r--deps/v8/test/cctest/compiler/test-loop-assignment-analysis.cc28
-rw-r--r--deps/v8/test/cctest/compiler/test-machine-operator-reducer.cc16
-rw-r--r--deps/v8/test/cctest/compiler/test-representation-change.cc2
-rw-r--r--deps/v8/test/cctest/compiler/test-run-bytecode-graph-builder.cc34
-rw-r--r--deps/v8/test/cctest/compiler/test-run-inlining.cc471
-rw-r--r--deps/v8/test/cctest/compiler/test-run-intrinsics.cc15
-rw-r--r--deps/v8/test/cctest/compiler/test-run-jscalls.cc1
-rw-r--r--deps/v8/test/cctest/compiler/test-run-machops.cc24
-rw-r--r--deps/v8/test/cctest/compiler/test-run-native-calls.cc52
-rw-r--r--deps/v8/test/cctest/compiler/test-run-variables.cc1
-rw-r--r--deps/v8/test/cctest/compiler/test-run-wasm-machops.cc44
-rw-r--r--deps/v8/test/cctest/heap/heap-tester.h1
-rw-r--r--deps/v8/test/cctest/heap/heap-utils.cc1
-rw-r--r--deps/v8/test/cctest/heap/test-alloc.cc6
-rw-r--r--deps/v8/test/cctest/heap/test-array-buffer-tracker.cc5
-rw-r--r--deps/v8/test/cctest/heap/test-heap.cc211
-rw-r--r--deps/v8/test/cctest/heap/test-incremental-marking.cc28
-rw-r--r--deps/v8/test/cctest/heap/test-mark-compact.cc34
-rw-r--r--deps/v8/test/cctest/heap/test-page-promotion.cc1
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode-expectations-printer.cc25
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/ArrayLiterals.golden16
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/ArrayLiteralsWide.golden2
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/AssignmentsInBinaryExpression.golden42
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/BasicLoops.golden166
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/BreakableBlocks.golden15
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/CallGlobal.golden10
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/CallLookupSlot.golden12
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/CallNew.golden15
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/CallRuntime.golden4
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/ClassAndSuperClass.golden28
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/ClassDeclarations.golden177
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/CompoundExpressions.golden6
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/ConstVariableContextSlot.golden16
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/ContextParameters.golden16
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/ContextVariables.golden25
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/CountOperators.golden14
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/CreateRestParameter.golden2
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/DeclareGlobals.golden7
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/Delete.golden4
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/ForIn.golden8
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/ForOf.golden199
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/FunctionLiterals.golden12
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/GenerateTestUndetectable.golden239
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/Generators.golden565
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/GlobalCompoundExpressions.golden8
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/GlobalCountOperators.golden16
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/GlobalDelete.golden12
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/LetVariableContextSlot.golden16
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/LoadGlobal.golden20
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/Modules.golden703
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/ObjectLiterals.golden98
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/OuterContextVariables.golden2
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/PrimitiveExpressions.golden40
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/PropertyCall.golden2
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/RemoveRedundantLdar.golden6
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/SuperCallAndSpread.golden155
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/Switch.golden2
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/TopLevelObjectLiterals.golden6
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/TryCatch.golden21
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/TryFinally.golden45
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/Typeof.golden5
-rw-r--r--deps/v8/test/cctest/interpreter/bytecode_expectations/UnaryOperators.golden21
-rw-r--r--deps/v8/test/cctest/interpreter/interpreter-tester.cc4
-rw-r--r--deps/v8/test/cctest/interpreter/test-bytecode-generator.cc95
-rw-r--r--deps/v8/test/cctest/interpreter/test-interpreter-intrinsics.cc21
-rw-r--r--deps/v8/test/cctest/interpreter/test-interpreter.cc25
-rw-r--r--deps/v8/test/cctest/interpreter/test-source-positions.cc4
-rw-r--r--deps/v8/test/cctest/libplatform/test-tracing.cc8
-rw-r--r--deps/v8/test/cctest/parsing/test-parse-decision.cc107
-rw-r--r--deps/v8/test/cctest/parsing/test-scanner-streams.cc31
-rw-r--r--deps/v8/test/cctest/parsing/test-scanner.cc37
-rw-r--r--deps/v8/test/cctest/test-access-checks.cc99
-rw-r--r--deps/v8/test/cctest/test-accessor-assembler.cc263
-rw-r--r--deps/v8/test/cctest/test-api-accessors.cc31
-rw-r--r--deps/v8/test/cctest/test-api-fast-accessor-builder.cc1
-rw-r--r--deps/v8/test/cctest/test-api-interceptors.cc128
-rw-r--r--deps/v8/test/cctest/test-api.cc984
-rw-r--r--deps/v8/test/cctest/test-assembler-arm.cc700
-rw-r--r--deps/v8/test/cctest/test-assembler-mips.cc6
-rw-r--r--deps/v8/test/cctest/test-assembler-mips64.cc6
-rw-r--r--deps/v8/test/cctest/test-assembler-s390.cc89
-rw-r--r--deps/v8/test/cctest/test-assembler-x64.cc183
-rw-r--r--deps/v8/test/cctest/test-ast.cc48
-rw-r--r--deps/v8/test/cctest/test-code-stub-assembler.cc1534
-rw-r--r--deps/v8/test/cctest/test-compiler.cc2
-rw-r--r--deps/v8/test/cctest/test-conversions.cc58
-rw-r--r--deps/v8/test/cctest/test-cpu-profiler.cc12
-rw-r--r--deps/v8/test/cctest/test-debug.cc1887
-rw-r--r--deps/v8/test/cctest/test-disasm-arm.cc187
-rw-r--r--deps/v8/test/cctest/test-extra.js3
-rw-r--r--deps/v8/test/cctest/test-feedback-vector.cc14
-rw-r--r--deps/v8/test/cctest/test-field-type-tracking.cc186
-rw-r--r--deps/v8/test/cctest/test-flags.cc2
-rw-r--r--deps/v8/test/cctest/test-global-handles.cc1
-rw-r--r--deps/v8/test/cctest/test-global-object.cc28
-rw-r--r--deps/v8/test/cctest/test-heap-profiler.cc96
-rw-r--r--deps/v8/test/cctest/test-inobject-slack-tracking.cc5
-rw-r--r--deps/v8/test/cctest/test-javascript-arm64.cc1
-rw-r--r--deps/v8/test/cctest/test-js-arm64-variables.cc1
-rw-r--r--deps/v8/test/cctest/test-liveedit.cc1
-rw-r--r--deps/v8/test/cctest/test-lockers.cc4
-rw-r--r--deps/v8/test/cctest/test-log.cc1
-rw-r--r--deps/v8/test/cctest/test-macro-assembler-arm.cc356
-rw-r--r--deps/v8/test/cctest/test-macro-assembler-mips.cc609
-rw-r--r--deps/v8/test/cctest/test-macro-assembler-mips64.cc791
-rw-r--r--deps/v8/test/cctest/test-object.cc1
-rw-r--r--deps/v8/test/cctest/test-parsing.cc1111
-rw-r--r--deps/v8/test/cctest/test-profile-generator.cc1
-rw-r--r--deps/v8/test/cctest/test-regexp.cc3
-rw-r--r--deps/v8/test/cctest/test-serialize.cc370
-rw-r--r--deps/v8/test/cctest/test-strings.cc36
-rw-r--r--deps/v8/test/cctest/test-thread-termination.cc5
-rw-r--r--deps/v8/test/cctest/test-transitions.cc19
-rw-r--r--deps/v8/test/cctest/test-typedarrays.cc1
-rw-r--r--deps/v8/test/cctest/test-unboxed-doubles.cc28
-rw-r--r--deps/v8/test/cctest/test-usecounters.cc43
-rw-r--r--deps/v8/test/cctest/test-weakmaps.cc1
-rw-r--r--deps/v8/test/cctest/wasm/OWNERS1
-rw-r--r--deps/v8/test/cctest/wasm/test-run-wasm-64.cc473
-rw-r--r--deps/v8/test/cctest/wasm/test-run-wasm-asmjs.cc177
-rw-r--r--deps/v8/test/cctest/wasm/test-run-wasm-interpreter.cc102
-rw-r--r--deps/v8/test/cctest/wasm/test-run-wasm-js.cc98
-rw-r--r--deps/v8/test/cctest/wasm/test-run-wasm-module.cc168
-rw-r--r--deps/v8/test/cctest/wasm/test-run-wasm-relocation.cc28
-rw-r--r--deps/v8/test/cctest/wasm/test-run-wasm-simd-lowering.cc262
-rw-r--r--deps/v8/test/cctest/wasm/test-run-wasm-simd.cc400
-rw-r--r--deps/v8/test/cctest/wasm/test-run-wasm.cc1431
-rw-r--r--deps/v8/test/cctest/wasm/test-wasm-breakpoints.cc70
-rw-r--r--deps/v8/test/cctest/wasm/test-wasm-stack.cc62
-rw-r--r--deps/v8/test/cctest/wasm/test-wasm-trap-position.cc54
-rw-r--r--deps/v8/test/cctest/wasm/wasm-run-utils.h675
143 files changed, 11664 insertions, 7503 deletions
diff --git a/deps/v8/test/cctest/BUILD.gn b/deps/v8/test/cctest/BUILD.gn
index f926707915..54e733c2dc 100644
--- a/deps/v8/test/cctest/BUILD.gn
+++ b/deps/v8/test/cctest/BUILD.gn
@@ -44,7 +44,6 @@ v8_executable("cctest") {
"compiler/test-run-bytecode-graph-builder.cc",
"compiler/test-run-calls-to-external-references.cc",
"compiler/test-run-deopt.cc",
- "compiler/test-run-inlining.cc",
"compiler/test-run-intrinsics.cc",
"compiler/test-run-jsbranches.cc",
"compiler/test-run-jscalls.cc",
@@ -91,6 +90,7 @@ v8_executable("cctest") {
"interpreter/test-source-positions.cc",
"libplatform/test-tracing.cc",
"libsampler/test-sampler.cc",
+ "parsing/test-parse-decision.cc",
"parsing/test-scanner-streams.cc",
"parsing/test-scanner.cc",
"print-extension.cc",
@@ -98,6 +98,7 @@ v8_executable("cctest") {
"profiler-extension.cc",
"profiler-extension.h",
"test-access-checks.cc",
+ "test-accessor-assembler.cc",
"test-accessors.cc",
"test-api-accessors.cc",
"test-api-fast-accessor-builder.cc",
@@ -190,6 +191,7 @@ v8_executable("cctest") {
"wasm/test-run-wasm-module.cc",
"wasm/test-run-wasm-relocation.cc",
"wasm/test-run-wasm.cc",
+ "wasm/test-wasm-breakpoints.cc",
"wasm/test-wasm-stack.cc",
"wasm/test-wasm-trap-position.cc",
"wasm/wasm-run-utils.h",
@@ -204,6 +206,7 @@ v8_executable("cctest") {
"test-disasm-arm.cc",
"test-macro-assembler-arm.cc",
"test-run-wasm-relocation-arm.cc",
+ "wasm/test-run-wasm-simd.cc",
]
} else if (v8_current_cpu == "arm64") {
sources += [ ### gcmole(arch:arm64) ###
@@ -218,6 +221,7 @@ v8_executable("cctest") {
"test-run-wasm-relocation-arm64.cc",
"test-utils-arm64.cc",
"test-utils-arm64.h",
+ "wasm/test-run-wasm-simd-lowering.cc",
]
} else if (v8_current_cpu == "x86") {
sources += [ ### gcmole(arch:ia32) ###
@@ -229,6 +233,7 @@ v8_executable("cctest") {
"test-log-stack-tracer.cc",
"test-macro-assembler-ia32.cc",
"test-run-wasm-relocation-ia32.cc",
+ "wasm/test-run-wasm-simd-lowering.cc",
]
} else if (v8_current_cpu == "mips") {
sources += [ ### gcmole(arch:mips) ###
@@ -238,6 +243,7 @@ v8_executable("cctest") {
"test-code-stubs.h",
"test-disasm-mips.cc",
"test-macro-assembler-mips.cc",
+ "wasm/test-run-wasm-simd-lowering.cc",
]
} else if (v8_current_cpu == "mipsel") {
sources += [ ### gcmole(arch:mipsel) ###
@@ -247,6 +253,7 @@ v8_executable("cctest") {
"test-code-stubs.h",
"test-disasm-mips.cc",
"test-macro-assembler-mips.cc",
+ "wasm/test-run-wasm-simd-lowering.cc",
]
} else if (v8_current_cpu == "mips64") {
sources += [ ### gcmole(arch:mips64) ###
@@ -256,6 +263,7 @@ v8_executable("cctest") {
"test-code-stubs.h",
"test-disasm-mips64.cc",
"test-macro-assembler-mips64.cc",
+ "wasm/test-run-wasm-simd-lowering.cc",
]
} else if (v8_current_cpu == "mips64el") {
sources += [ ### gcmole(arch:mips64el) ###
@@ -265,6 +273,7 @@ v8_executable("cctest") {
"test-code-stubs.h",
"test-disasm-mips64.cc",
"test-macro-assembler-mips64.cc",
+ "wasm/test-run-wasm-simd-lowering.cc",
]
} else if (v8_current_cpu == "x64") {
sources += [ ### gcmole(arch:x64) ###
@@ -276,7 +285,6 @@ v8_executable("cctest") {
"test-log-stack-tracer.cc",
"test-macro-assembler-x64.cc",
"test-run-wasm-relocation-x64.cc",
- "wasm/test-run-wasm-simd-lowering.cc",
"wasm/test-run-wasm-simd.cc",
]
} else if (v8_current_cpu == "x87") {
@@ -289,6 +297,7 @@ v8_executable("cctest") {
"test-log-stack-tracer.cc",
"test-macro-assembler-x87.cc",
"test-run-wasm-relocation-x87.cc",
+ "wasm/test-run-wasm-simd-lowering.cc",
]
} else if (v8_current_cpu == "ppc" || v8_current_cpu == "ppc64") {
sources += [ ### gcmole(arch:ppc) ###
@@ -296,6 +305,7 @@ v8_executable("cctest") {
"test-code-stubs.cc",
"test-code-stubs.h",
"test-disasm-ppc.cc",
+ "wasm/test-run-wasm-simd-lowering.cc",
]
} else if (v8_current_cpu == "s390" || v8_current_cpu == "s390x") {
sources += [ ### gcmole(arch:s390) ###
@@ -303,6 +313,7 @@ v8_executable("cctest") {
"test-code-stubs.cc",
"test-code-stubs.h",
"test-disasm-s390.cc",
+ "wasm/test-run-wasm-simd-lowering.cc",
]
}
@@ -347,9 +358,16 @@ v8_executable("cctest") {
cflags = []
ldflags = []
+ # crbug.com/676417: Suppress symbol import warning from linker.
+ if (is_win && is_component_build) {
+ ldflags = [ "/ignore:4217" ]
+ }
+
if (v8_current_cpu == "ppc" || v8_current_cpu == "ppc64" ||
v8_current_cpu == "arm" || v8_current_cpu == "arm64" ||
- v8_current_cpu == "s390" || v8_current_cpu == "s390x") {
+ v8_current_cpu == "s390" || v8_current_cpu == "s390x" ||
+ v8_current_cpu == "mips" || v8_current_cpu == "mips64" ||
+ v8_current_cpu == "mipsel" || v8_current_cpu == "mipsel64") {
# Disable fmadd/fmsub so that expected results match generated code in
# RunFloat64MulAndFloat64Add1 and friends.
cflags += [ "-ffp-contract=off" ]
diff --git a/deps/v8/test/cctest/asmjs/OWNERS b/deps/v8/test/cctest/asmjs/OWNERS
index d8fad3059a..509581c8db 100644
--- a/deps/v8/test/cctest/asmjs/OWNERS
+++ b/deps/v8/test/cctest/asmjs/OWNERS
@@ -4,6 +4,7 @@ set noparent
ahaas@chromium.org
bradnelson@chromium.org
+clemensh@chromium.org
jpp@chromium.org
mtrofin@chromium.org
rossberg@chromium.org
diff --git a/deps/v8/test/cctest/asmjs/test-asm-typer.cc b/deps/v8/test/cctest/asmjs/test-asm-typer.cc
index d345774dbf..892c968d1d 100644
--- a/deps/v8/test/cctest/asmjs/test-asm-typer.cc
+++ b/deps/v8/test/cctest/asmjs/test-asm-typer.cc
@@ -14,6 +14,7 @@
#include "src/ast/scopes.h"
#include "src/base/platform/platform.h"
#include "src/compiler.h"
+#include "src/objects-inl.h"
#include "src/parsing/parse-info.h"
#include "src/parsing/parser.h"
#include "src/v8.h"
@@ -46,7 +47,8 @@ class AsmTyperHarnessBuilder {
handles_(),
zone_(handles_.main_zone()),
isolate_(CcTest::i_isolate()),
- ast_value_factory_(zone_, isolate_->heap()->HashSeed()),
+ ast_value_factory_(zone_, isolate_->ast_string_constants(),
+ isolate_->heap()->HashSeed()),
factory_(isolate_->factory()),
source_code_(
factory_->NewStringFromUtf8(CStrVector(source)).ToHandleChecked()),
@@ -69,7 +71,7 @@ class AsmTyperHarnessBuilder {
->AtForTest(0)
->AsFunctionDeclaration()
->fun();
- typer_.reset(new AsmTyper(isolate_, zone_, *script_, module_));
+ typer_.reset(new AsmTyper(isolate_, zone_, script_, module_));
if (validation_type_ == ValidateStatement ||
validation_type_ == ValidateExpression) {
@@ -99,6 +101,9 @@ class AsmTyperHarnessBuilder {
CHECK(validation_type_ == ValidateStatement ||
validation_type_ == ValidateExpression);
auto* var = DeclareVariable(var_name);
+ if (var->IsUnallocated()) {
+ var->AllocateTo(VariableLocation::LOCAL, -1);
+ }
auto* var_info = new (zone_) AsmTyper::VariableInfo(type);
var_info->set_mutability(AsmTyper::VariableInfo::kLocal);
CHECK(typer_->AddLocal(var, var_info));
@@ -107,9 +112,14 @@ class AsmTyperHarnessBuilder {
AsmTyperHarnessBuilder* WithGlobal(VariableName var_name, AsmType* type) {
auto* var = DeclareVariable(var_name);
- auto* var_info = new (zone_) AsmTyper::VariableInfo(type);
- var_info->set_mutability(AsmTyper::VariableInfo::kMutableGlobal);
- CHECK(typer_->AddGlobal(var, var_info));
+ if (var->IsUnallocated()) {
+ var->AllocateTo(VariableLocation::MODULE, -1);
+ }
+ if (type != nullptr) {
+ auto* var_info = new (zone_) AsmTyper::VariableInfo(type);
+ var_info->set_mutability(AsmTyper::VariableInfo::kMutableGlobal);
+ CHECK(typer_->AddGlobal(var, var_info));
+ }
return this;
}
@@ -126,13 +136,17 @@ class AsmTyperHarnessBuilder {
WithGlobal(var_name, type);
auto* var_info = typer_->Lookup(DeclareVariable(var_name));
CHECK(var_info);
- var_info->FirstForwardUseIs(nullptr);
+ MessageLocation location;
+ var_info->SetFirstForwardUse(location);
return this;
}
AsmTyperHarnessBuilder* WithImport(VariableName var_name,
AsmTyper::StandardMember standard_member) {
auto* var = DeclareVariable(var_name);
+ if (var->IsUnallocated()) {
+ var->AllocateTo(VariableLocation::LOCAL, -1);
+ }
AsmTyper::VariableInfo* var_info = nullptr;
auto* stdlib_map = &typer_->stdlib_math_types_;
switch (standard_member) {
@@ -217,7 +231,9 @@ class AsmTyperHarnessBuilder {
return true;
}
- std::cerr << "Asm validation failed: " << typer_->error_message() << "\n";
+ std::unique_ptr<char[]> msg = i::MessageHandler::GetLocalizedMessage(
+ isolate_, typer_->error_message());
+ std::cerr << "Asm validation failed: " << msg.get() << "\n";
return false;
}
@@ -225,7 +241,9 @@ class AsmTyperHarnessBuilder {
CHECK(validation_type_ == ValidateExpression);
auto* validated_as = ValidateExpressionStatment(fun_decl_);
if (validated_as == AsmType::None()) {
- std::cerr << "Validation failure: " << typer_->error_message() << "\n";
+ std::unique_ptr<char[]> msg = i::MessageHandler::GetLocalizedMessage(
+ isolate_, typer_->error_message());
+ std::cerr << "Validation failure: " << msg.get() << "\n";
return false;
} else if (validated_as != type) {
std::cerr << "Validation succeeded with wrong type "
@@ -260,12 +278,14 @@ class AsmTyperHarnessBuilder {
return false;
}
- if (std::strstr(typer_->error_message(), error_message) == nullptr) {
+ std::unique_ptr<char[]> msg = i::MessageHandler::GetLocalizedMessage(
+ isolate_, typer_->error_message());
+ if (std::strstr(msg.get(), error_message) == nullptr) {
std::cerr << "Asm validation failed with the wrong error message:\n"
"Expected to contain '"
<< error_message << "'\n"
" Actually is '"
- << typer_->error_message() << "'\n";
+ << msg.get() << "'\n";
return false;
}
@@ -671,12 +691,18 @@ TEST(ErrorsInModuleExport) {
{"return {'a': ffi}", "cannot export foreign functions"},
{"return {'a': f()}", "must be an asm.js function name"},
{"return {'a': f}", "Undefined identifier in asm.js module export"},
- {"function v() { a(); } return {b: d2s}", "Missing definition for forw"},
- {"return {b: d2s, 'a': d2s_tbl}", "cannot export function tables"},
- {"return {b: d2s, 'a': min}", "cannot export standard library"},
- {"return {b: d2s, 'a': ffi}", "cannot export foreign functions"},
- {"return {b: d2s, 'a': f()}", "must be an asm.js function name"},
- {"return {b: d2s, 'a': f}", "Undefined identifier in asm.js module"},
+ {"function v() { a(); } return {b: d2s}",
+ "Invalid call of existing global function"},
+ {"function v() {} return {b: v, 'a': d2s_tbl}",
+ "cannot export function tables"},
+ {"function v() {} return {b: v, 'a': min}",
+ "cannot export standard library"},
+ {"function v() {} return {b: v, 'a': ffi}",
+ "cannot export foreign functions"},
+ {"function v() {} return {b: v, 'a': f()}",
+ "must be an asm.js function name"},
+ {"function v() {} return {b: v, 'a': f}",
+ "Undefined identifier in asm.js module"},
};
auto d2s_tbl = [](Zone* zone) -> iw::AsmType* {
@@ -687,17 +713,10 @@ TEST(ErrorsInModuleExport) {
return ret;
};
- auto d2s = [](Zone* zone) -> iw::AsmType* {
- auto* ret = iw::AsmType::Function(zone, iw::AsmType::Signed());
- ret->AsFunctionType()->AddArgument(iw::AsmType::Double());
- return ret;
- };
-
for (size_t ii = 0; ii < arraysize(kTests); ++ii) {
const auto* test = kTests + ii;
if (!ValidationOf(Export(test->module_export))
->WithGlobal(DynamicGlobal("d2s_tbl"), d2s_tbl)
- ->WithGlobal(DynamicGlobal("d2s"), d2s)
->WithImport(DynamicGlobal("min"), iw::AsmTyper::kMathMin)
->WithImport(DynamicGlobal("ffi"), iw::AsmTyper::kFFI)
->WithGlobal(DynamicGlobal("I"), iw::AsmType::Int())
@@ -910,6 +929,7 @@ TEST(ErrorsInStatement) {
->WithImport(DynamicGlobal("fround"), iw::AsmTyper::kMathFround)
->WithLocal(DynamicGlobal("flocal"), iw::AsmType::Float())
->WithLocal(DynamicGlobal("slocal"), iw::AsmType::Signed())
+ ->WithGlobal(DynamicGlobal("d"), nullptr)
->FailsWithMessage(test->error_message)) {
std::cerr << "Test:\n" << test->statement;
CHECK(false);
@@ -1040,6 +1060,7 @@ TEST(ErrorsInExpression) {
->WithGlobal(DynamicGlobal("d2s_tbl"), d2s_tbl)
->WithGlobal(DynamicGlobal("HEAP32"), iw::AsmType::Int32Array())
->WithGlobal(DynamicGlobal("HEAP8"), iw::AsmType::Int8Array())
+ ->WithGlobal(DynamicGlobal("a"), nullptr)
->FailsWithMessage(test->error_message)) {
std::cerr << "Test:\n" << test->expression;
CHECK(false);
@@ -1367,6 +1388,8 @@ TEST(ValidateAssignmentExpression) {
->WithGlobal(DynamicGlobal("U32"), iw::AsmType::Uint32Array())
->WithGlobal(DynamicGlobal("F32"), iw::AsmType::Float32Array())
->WithGlobal(DynamicGlobal("F64"), iw::AsmType::Float64Array())
+ ->WithGlobal(DynamicGlobal("make_float"), nullptr)
+ ->WithGlobal(DynamicGlobal("make_double"), nullptr)
->SucceedsWithExactType(test->load_type)) {
std::cerr << "Test:\n" << test->expression;
CHECK(false);
@@ -1422,6 +1445,7 @@ TEST(ValidateUnaryExpression) {
->WithLocal(DynamicGlobal("ulocal"), iw::AsmType::Unsigned())
->WithLocal(DynamicGlobal("ilocal"), iw::AsmType::Int())
->WithGlobal(DynamicGlobal("dglobal"), iw::AsmType::Double())
+ ->WithGlobal(DynamicGlobal("make_double"), nullptr)
->WithGlobal(DynamicGlobal("dbl"), v2d)
->SucceedsWithExactType(test->load_type)) {
std::cerr << "Test:\n" << test->expression;
@@ -1671,6 +1695,7 @@ TEST(ValidateBitwiseExpression) {
->WithLocal(DynamicGlobal("iish1"), iw::AsmType::Intish())
->WithLocal(DynamicGlobal("iish0"), iw::AsmType::Intish())
->WithGlobal(DynamicGlobal("signed"), v2s)
+ ->WithGlobal(DynamicGlobal("make_signed"), nullptr)
->SucceedsWithExactType(test->load_type)) {
std::cerr << "Test:\n" << test->expression;
CHECK(false);
@@ -1718,7 +1743,7 @@ TEST(ValidateCall) {
//
// ifd2_(&iw::AsmType::Float)
//
- // returns an AsmType representing an asm.j function with the following
+ // returns an AsmType representing an asm.js function with the following
// signature:
//
// float(int, float, double)
@@ -1795,6 +1820,9 @@ TEST(ValidateCall) {
->WithLocal(DynamicGlobal("u"), iw::AsmType::Unsigned())
->WithLocal(DynamicGlobal("iish"), iw::AsmType::Intish())
->WithGlobal(DynamicGlobal("v2f"), v2f)
+ ->WithGlobal(DynamicGlobal("ifd2f"), nullptr)
+ ->WithGlobal(DynamicGlobal("ifd2d"), nullptr)
+ ->WithGlobal(DynamicGlobal("ifd2i"), nullptr)
->WithGlobal(DynamicGlobal("ifd2f_tbl"), ifd2f_tbl)
->WithGlobal(DynamicGlobal("ifd2d_tbl"), ifd2d_tbl)
->WithGlobal(DynamicGlobal("ifd2i_tbl"), ifd2i_tbl)
diff --git a/deps/v8/test/cctest/cctest.gyp b/deps/v8/test/cctest/cctest.gyp
index 6b5dba6472..1eff6c0c6d 100644
--- a/deps/v8/test/cctest/cctest.gyp
+++ b/deps/v8/test/cctest/cctest.gyp
@@ -64,7 +64,6 @@
'compiler/test-run-bytecode-graph-builder.cc',
'compiler/test-run-calls-to-external-references.cc',
'compiler/test-run-deopt.cc',
- 'compiler/test-run-inlining.cc',
'compiler/test-run-intrinsics.cc',
'compiler/test-run-jsbranches.cc',
'compiler/test-run-jscalls.cc',
@@ -112,6 +111,7 @@
'heap/test-spaces.cc',
'libplatform/test-tracing.cc',
'libsampler/test-sampler.cc',
+ 'parsing/test-parse-decision.cc',
'parsing/test-scanner-streams.cc',
'parsing/test-scanner.cc',
'print-extension.cc',
@@ -119,6 +119,7 @@
'profiler-extension.cc',
'profiler-extension.h',
'test-access-checks.cc',
+ 'test-accessor-assembler.cc',
'test-accessors.cc',
'test-api.cc',
'test-api.h',
@@ -211,6 +212,7 @@
'wasm/test-run-wasm-js.cc',
'wasm/test-run-wasm-module.cc',
'wasm/test-run-wasm-relocation.cc',
+ 'wasm/test-wasm-breakpoints.cc',
'wasm/test-wasm-stack.cc',
'wasm/test-wasm-trap-position.cc',
'wasm/wasm-run-utils.h',
@@ -223,7 +225,8 @@
'test-disasm-ia32.cc',
'test-macro-assembler-ia32.cc',
'test-log-stack-tracer.cc',
- 'test-run-wasm-relocation-ia32.cc'
+ 'test-run-wasm-relocation-ia32.cc',
+ 'wasm/test-run-wasm-simd-lowering.cc'
],
'cctest_sources_x64': [ ### gcmole(arch:x64) ###
'test-assembler-x64.cc',
@@ -235,7 +238,6 @@
'test-log-stack-tracer.cc',
'test-run-wasm-relocation-x64.cc',
'wasm/test-run-wasm-simd.cc',
- 'wasm/test-run-wasm-simd-lowering.cc',
],
'cctest_sources_arm': [ ### gcmole(arch:arm) ###
'test-assembler-arm.cc',
@@ -244,7 +246,8 @@
'test-code-stubs-arm.cc',
'test-disasm-arm.cc',
'test-macro-assembler-arm.cc',
- 'test-run-wasm-relocation-arm.cc'
+ 'test-run-wasm-relocation-arm.cc',
+ 'wasm/test-run-wasm-simd-lowering.cc'
],
'cctest_sources_arm64': [ ### gcmole(arch:arm64) ###
'test-utils-arm64.cc',
@@ -257,19 +260,22 @@
'test-fuzz-arm64.cc',
'test-javascript-arm64.cc',
'test-js-arm64-variables.cc',
- 'test-run-wasm-relocation-arm64.cc'
+ 'test-run-wasm-relocation-arm64.cc',
+ 'wasm/test-run-wasm-simd-lowering.cc'
],
'cctest_sources_s390': [ ### gcmole(arch:s390) ###
'test-assembler-s390.cc',
'test-code-stubs.cc',
'test-code-stubs.h',
- 'test-disasm-s390.cc'
+ 'test-disasm-s390.cc',
+ 'wasm/test-run-wasm-simd-lowering.cc'
],
'cctest_sources_ppc': [ ### gcmole(arch:ppc) ###
'test-assembler-ppc.cc',
'test-code-stubs.cc',
'test-code-stubs.h',
- 'test-disasm-ppc.cc'
+ 'test-disasm-ppc.cc',
+ 'wasm/test-run-wasm-simd-lowering.cc'
],
'cctest_sources_mips': [ ### gcmole(arch:mips) ###
'test-assembler-mips.cc',
@@ -277,7 +283,8 @@
'test-code-stubs.h',
'test-code-stubs-mips.cc',
'test-disasm-mips.cc',
- 'test-macro-assembler-mips.cc'
+ 'test-macro-assembler-mips.cc',
+ 'wasm/test-run-wasm-simd-lowering.cc'
],
'cctest_sources_mipsel': [ ### gcmole(arch:mipsel) ###
'test-assembler-mips.cc',
@@ -285,7 +292,8 @@
'test-code-stubs.h',
'test-code-stubs-mips.cc',
'test-disasm-mips.cc',
- 'test-macro-assembler-mips.cc'
+ 'test-macro-assembler-mips.cc',
+ 'wasm/test-run-wasm-simd-lowering.cc'
],
'cctest_sources_mips64': [ ### gcmole(arch:mips64) ###
'test-assembler-mips64.cc',
@@ -293,7 +301,8 @@
'test-code-stubs.h',
'test-code-stubs-mips64.cc',
'test-disasm-mips64.cc',
- 'test-macro-assembler-mips64.cc'
+ 'test-macro-assembler-mips64.cc',
+ 'wasm/test-run-wasm-simd-lowering.cc'
],
'cctest_sources_mips64el': [ ### gcmole(arch:mips64el) ###
'test-assembler-mips64.cc',
@@ -301,7 +310,8 @@
'test-code-stubs.h',
'test-code-stubs-mips64.cc',
'test-disasm-mips64.cc',
- 'test-macro-assembler-mips64.cc'
+ 'test-macro-assembler-mips64.cc',
+ 'wasm/test-run-wasm-simd-lowering.cc'
],
'cctest_sources_x87': [ ### gcmole(arch:x87) ###
'test-assembler-x87.cc',
@@ -311,7 +321,8 @@
'test-disasm-x87.cc',
'test-macro-assembler-x87.cc',
'test-log-stack-tracer.cc',
- 'test-run-wasm-relocation-x87.cc'
+ 'test-run-wasm-relocation-x87.cc',
+ 'wasm/test-run-wasm-simd-lowering.cc'
],
},
'includes': ['../../gypfiles/toolchain.gypi', '../../gypfiles/features.gypi'],
@@ -418,7 +429,9 @@
}],
['v8_target_arch=="ppc" or v8_target_arch=="ppc64" \
or v8_target_arch=="arm" or v8_target_arch=="arm64" \
- or v8_target_arch=="s390" or v8_target_arch=="s390x"', {
+ or v8_target_arch=="s390" or v8_target_arch=="s390x" \
+ or v8_target_arch=="mips" or v8_target_arch=="mips64" \
+ or v8_target_arch=="mipsel" or v8_target_arch=="mips64el"', {
# disable fmadd/fmsub so that expected results match generated code in
# RunFloat64MulAndFloat64Add1 and friends.
'cflags': ['-ffp-contract=off'],
diff --git a/deps/v8/test/cctest/cctest.h b/deps/v8/test/cctest/cctest.h
index 690a8c14cd..7d8ad59a26 100644
--- a/deps/v8/test/cctest/cctest.h
+++ b/deps/v8/test/cctest/cctest.h
@@ -583,7 +583,6 @@ class InitializedHandleScope {
std::unique_ptr<InitializedHandleScopeImpl> initialized_handle_scope_impl_;
};
-
class HandleAndZoneScope : public InitializedHandleScope {
public:
HandleAndZoneScope();
@@ -597,4 +596,18 @@ class HandleAndZoneScope : public InitializedHandleScope {
std::unique_ptr<i::Zone> main_zone_;
};
+class StaticOneByteResource : public v8::String::ExternalOneByteStringResource {
+ public:
+ explicit StaticOneByteResource(const char* data) : data_(data) {}
+
+ ~StaticOneByteResource() {}
+
+ const char* data() const { return data_; }
+
+ size_t length() const { return strlen(data_); }
+
+ private:
+ const char* data_;
+};
+
#endif // ifndef CCTEST_H_
diff --git a/deps/v8/test/cctest/cctest.status b/deps/v8/test/cctest/cctest.status
index 059d099bf5..e5ac07cd0e 100644
--- a/deps/v8/test/cctest/cctest.status
+++ b/deps/v8/test/cctest/cctest.status
@@ -77,9 +77,6 @@
'test-cpu-profiler/HotDeoptNoFrameEntry': [SKIP],
'test-cpu-profiler/SampleWhenFrameIsNotSetup': [SKIP],
- # BUG(v8:4358). Hangs flakily.
- 'test-debug/ProcessDebugMessagesThreaded': [SKIP],
-
# BUG(2340). Preprocessing stack traces is disabled at the moment.
'test-heap/PreprocessStackTrace': [FAIL],
@@ -87,6 +84,13 @@
'test-func-name-inference/UpperCaseClass': [FAIL],
'test-func-name-inference/LowerCaseClass': [FAIL],
+ # Bug(5784). StubCache tests need to be redesigned, as a) they don't work
+ # in the new (ignition + turbofan) pipeline environment, and b) they are
+ # stymied by a move of code stubs into builtins.
+ 'test-api/PrimaryStubCache': [SKIP],
+ 'test-api/SecondaryStubCache': [SKIP],
+ 'test-api/AccessCheckInIC': [SKIP],
+
# BUG(3742).
'test-mark-compact/MarkCompactCollector': [PASS, ['arch==arm', NO_VARIANTS]],
@@ -201,6 +205,9 @@
'test-cpu-profiler/JsNativeJsSample': [SKIP],
'test-cpu-profiler/JsNative1JsNative2JsSample': [SKIP],
+ # BUG(v8:5193): Flaky.
+ 'test-cpu-profiler/FunctionApplySample': [SKIP],
+
# BUG(5193): Flaky timeout.
'test-sampler/LibSamplerCollectSample': [PASS, ['arch == x64', SKIP]],
}], # 'system == windows'
@@ -218,6 +225,10 @@
'test-serialize/StartupSerializerTwice': [SKIP],
'test-serialize/StartupSerializerOnceRunScript': [SKIP],
'test-serialize/StartupSerializerTwiceRunScript': [SKIP],
+ 'test-run-wasm-simd/RunWasmCompiled_F32x4Add': [SKIP],
+ 'test-run-wasm-simd/RunWasmCompiled_F32x4Sub': [SKIP],
+ 'test-run-wasm-simd/RunWasmInterpreted_F32x4Add': [SKIP],
+ 'test-run-wasm-simd/RunWasmInterpreted_F32x4Sub': [SKIP],
############################################################################
# Slow tests.
@@ -326,80 +337,47 @@
##############################################################################
['variant == turbofan_opt', {
- # TODO(mythria,4680): Lack of code-ageing and/or lack of compilation cache
- # in interpreter.
- 'test-heap/CompilationCacheCachingBehavior': [FAIL],
-
- # TODO(mstarzinger): Triggers Ignition+TurboFan on everything now and makes
- # the stack traces within the profilers look different. Needs investigation.
- 'test-api/SetFunctionEntryHook': [SKIP],
- 'test-cpu-profiler/BoundFunctionCall': [FAIL],
- 'test-cpu-profiler/CollectSampleAPI': [FAIL],
- 'test-cpu-profiler/FunctionApplySample': [FAIL],
- 'test-cpu-profiler/FunctionCallSample': [FAIL],
- 'test-cpu-profiler/JsNativeJsRuntimeJsSample': [FAIL],
- 'test-cpu-profiler/JsNativeJsSample': [FAIL],
- 'test-cpu-profiler/JsNativeJsRuntimeJsSampleMultiple': [FAIL],
- 'test-cpu-profiler/JsNative1JsNative2JsSample': [FAIL],
- 'test-cpu-profiler/NativeMethodUninitializedIC': [FAIL],
- 'test-cpu-profiler/NativeAccessorUninitializedIC': [FAIL],
- 'test-profile-generator/LineNumber': [FAIL],
- 'test-sampler-api/StackFramesConsistent': [FAIL],
-
# BUG(v8:5457)
'test-api/SetJitCodeEventHandler': [PASS, ['no_snap', SKIP]],
}], # variant == turbofan_opt
##############################################################################
-['variant == ignition', {
- # TODO(mythria,4680): Lack of code-ageing and/or lack of compilation cache
- # in interpreter.
- 'test-heap/CompilationCacheCachingBehavior': [FAIL],
-
- # BUG(5193): Flaky.
- 'test-cpu-profiler/FunctionApplySample': [PASS, ['system == windows', SKIP]],
-}], # variant == ignition
-
-##############################################################################
-['variant == ignition_staging', {
- 'test-cpu-profiler/DeoptUntrackedFunction': [SKIP],
- 'test-cpu-profiler/TickLinesOptimized': [SKIP],
- 'test-heap/CompilationCacheCachingBehavior': [FAIL],
-
- # BUG(5193): Flaky.
- 'test-cpu-profiler/FunctionApplySample': [PASS, ['system == windows', SKIP]],
-}], # variant == ignition_staging
-
-##############################################################################
['variant == turbofan or variant == ignition_turbofan', {
- # TODO(mythria,4680): Lack of code-ageing and/or lack of compilation cache
- # in interpreter.
- 'test-heap/CompilationCacheCachingBehavior': [FAIL],
-
- # BUG(4680): Missing type feedback makes optimistic optimizations fail.
- 'test-cpu-profiler/CollectDeoptEvents': [FAIL],
- 'test-cpu-profiler/DeoptUntrackedFunction': [SKIP],
-
# BUG(4751). Flaky with Ignition.
'test-cpu-profiler/JsNativeJsSample': [SKIP],
# TODO(vogelheim,5548): Turbofan does support cached accessors.
'test-api-accessors/CachedAccessorCrankshaft': [FAIL],
-
- # BUG(5193): Flaky.
- 'test-cpu-profiler/FunctionApplySample': [PASS, ['system == windows', SKIP]],
}], # variant == turbofan or variant == ignition_turbofan
##############################################################################
-['variant != ignition and variant != ignition_staging and variant != ignition_turbofan', {
- # Ongoing implementation of modules.
- # https://bugs.chromium.org/p/v8/issues/detail?id=1569
- 'test-modules/*': [SKIP],
-}], # variant != ignition and variant != ignition_staging and variant != ignition_turbofan
-
-##############################################################################
['variant == asm_wasm', {
'*': [SKIP],
}], # variant == asm_wasm
+##############################################################################
+['variant == wasm_traps', {
+ 'test-accessors/*': [SKIP],
+ 'test-api-interceptors/*': [SKIP],
+ 'test-api/*': [SKIP],
+ 'test-bignum-dtoa/*': [SKIP],
+ 'test-cpu-profiler/*': [SKIP],
+ 'test-debug/*': [SKIP],
+ 'test-global-handles/*': [SKIP],
+ 'test-heap-profiler/*': [SKIP],
+ 'test-heap/*': [SKIP],
+ 'test-inobject-slack-tracking/*': [SKIP],
+ 'test-lockers/*': [SKIP],
+ 'test-run-machops/*': [SKIP],
+ 'test-serialize/*': [SKIP],
+ 'test-strings/*': [SKIP],
+ 'test-field-type-tracking/*': [SKIP],
+ 'test-parsing/*': [SKIP],
+ 'test-page-promotion/*': [SKIP],
+ 'test-decls/*': [SKIP],
+ 'test-log/*': [SKIP],
+ 'test-gap-resolver/*': [SKIP],
+ 'test-dtoa/*': [SKIP],
+}], # variant == wasm_traps
+
]
diff --git a/deps/v8/test/cctest/compiler/code-assembler-tester.h b/deps/v8/test/cctest/compiler/code-assembler-tester.h
index b0c84ec94a..f49e8c55c9 100644
--- a/deps/v8/test/cctest/compiler/code-assembler-tester.h
+++ b/deps/v8/test/cctest/compiler/code-assembler-tester.h
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "src/compiler/code-assembler.h"
#include "src/handles.h"
#include "src/interface-descriptors.h"
#include "src/isolate.h"
@@ -11,51 +12,43 @@ namespace v8 {
namespace internal {
namespace compiler {
-class ZoneHolder {
+class CodeAssemblerTester {
public:
- explicit ZoneHolder(Isolate* isolate)
- : held_zone_(isolate->allocator(), ZONE_NAME) {}
- Zone* held_zone() { return &held_zone_; }
-
- private:
- Zone held_zone_;
-};
-
-// Inherit from ZoneHolder in order to create a zone that can be passed to
-// CodeAssembler base class constructor.
-template <typename CodeAssemblerT>
-class CodeAssemblerTesterImpl : private ZoneHolder, public CodeAssemblerT {
- public:
- // Test generating code for a stub.
- CodeAssemblerTesterImpl(Isolate* isolate,
- const CallInterfaceDescriptor& descriptor)
- : ZoneHolder(isolate),
- CodeAssemblerT(isolate, ZoneHolder::held_zone(), descriptor,
- Code::ComputeFlags(Code::STUB), "test"),
- scope_(isolate) {}
+ // Test generating code for a stub. Assumes VoidDescriptor call interface.
+ explicit CodeAssemblerTester(Isolate* isolate)
+ : zone_(isolate->allocator(), ZONE_NAME),
+ scope_(isolate),
+ state_(isolate, &zone_, VoidDescriptor(isolate),
+ Code::ComputeFlags(Code::STUB), "test") {}
// Test generating code for a JS function (e.g. builtins).
- CodeAssemblerTesterImpl(Isolate* isolate, int parameter_count,
- Code::Kind kind = Code::BUILTIN)
- : ZoneHolder(isolate),
- CodeAssemblerT(isolate, ZoneHolder::held_zone(), parameter_count,
- Code::ComputeFlags(kind), "test"),
- scope_(isolate) {}
+ CodeAssemblerTester(Isolate* isolate, int parameter_count,
+ Code::Kind kind = Code::BUILTIN)
+ : zone_(isolate->allocator(), ZONE_NAME),
+ scope_(isolate),
+ state_(isolate, &zone_, parameter_count, Code::ComputeFlags(kind),
+ "test") {}
// This constructor is intended to be used for creating code objects with
// specific flags.
- CodeAssemblerTesterImpl(Isolate* isolate, Code::Flags flags)
- : ZoneHolder(isolate),
- CodeAssemblerT(isolate, ZoneHolder::held_zone(), 0, flags, "test"),
- scope_(isolate) {}
+ CodeAssemblerTester(Isolate* isolate, Code::Flags flags)
+ : zone_(isolate->allocator(), ZONE_NAME),
+ scope_(isolate),
+ state_(isolate, &zone_, 0, flags, "test") {}
+
+ CodeAssemblerState* state() { return &state_; }
+
+ Handle<Code> GenerateCode() { return CodeAssembler::GenerateCode(&state_); }
Handle<Code> GenerateCodeCloseAndEscape() {
- return scope_.CloseAndEscape(CodeAssemblerT::GenerateCode());
+ return scope_.CloseAndEscape(GenerateCode());
}
private:
+ Zone zone_;
HandleScope scope_;
LocalContext context_;
+ CodeAssemblerState state_;
};
} // namespace compiler
diff --git a/deps/v8/test/cctest/compiler/function-tester.cc b/deps/v8/test/cctest/compiler/function-tester.cc
index 24a49b852c..c88713a6dc 100644
--- a/deps/v8/test/cctest/compiler/function-tester.cc
+++ b/deps/v8/test/cctest/compiler/function-tester.cc
@@ -14,7 +14,7 @@
#include "src/handles.h"
#include "src/objects-inl.h"
#include "src/parsing/parse-info.h"
-#include "src/parsing/parser.h"
+#include "src/parsing/parsing.h"
#include "test/cctest/cctest.h"
namespace v8 {
@@ -46,9 +46,7 @@ FunctionTester::FunctionTester(Handle<Code> code, int param_count)
function->ReplaceCode(*code);
}
-FunctionTester::FunctionTester(const CallInterfaceDescriptor& descriptor,
- Handle<Code> code)
- : FunctionTester(code, descriptor.GetParameterCount()) {}
+FunctionTester::FunctionTester(Handle<Code> code) : FunctionTester(code, 0) {}
MaybeHandle<Object> FunctionTester::Call() {
return Execution::Call(isolate, function, undefined(), 0, nullptr);
@@ -166,7 +164,9 @@ Handle<JSFunction> FunctionTester::Compile(Handle<JSFunction> function) {
if (flags_ & CompilationInfo::kInliningEnabled) {
info.MarkAsInliningEnabled();
}
- if (Compiler::EnsureBytecode(&info)) {
+
+ CHECK(Compiler::Compile(function, Compiler::CLEAR_EXCEPTION));
+ if (info.shared_info()->HasBytecodeArray()) {
info.MarkAsOptimizeFromBytecode();
} else {
CHECK(Compiler::ParseAndAnalyze(info.parse_info()));
@@ -189,7 +189,7 @@ Handle<JSFunction> FunctionTester::CompileGraph(Graph* graph) {
ParseInfo parse_info(&zone, handle(function->shared()));
CompilationInfo info(&parse_info, function);
- CHECK(Parser::ParseStatic(info.parse_info()));
+ CHECK(parsing::ParseFunction(info.parse_info()));
info.SetOptimizing();
Handle<Code> code = Pipeline::GenerateCodeForTesting(&info, graph);
diff --git a/deps/v8/test/cctest/compiler/function-tester.h b/deps/v8/test/cctest/compiler/function-tester.h
index e65fa78c13..07363a0f25 100644
--- a/deps/v8/test/cctest/compiler/function-tester.h
+++ b/deps/v8/test/cctest/compiler/function-tester.h
@@ -26,7 +26,8 @@ class FunctionTester : public InitializedHandleScope {
FunctionTester(Handle<Code> code, int param_count);
- FunctionTester(const CallInterfaceDescriptor& descriptor, Handle<Code> code);
+ // Assumes VoidDescriptor call interface.
+ explicit FunctionTester(Handle<Code> code);
Isolate* isolate;
Handle<JSFunction> function;
diff --git a/deps/v8/test/cctest/compiler/test-code-assembler.cc b/deps/v8/test/cctest/compiler/test-code-assembler.cc
index 6fe733af8d..90fdc2b7ae 100644
--- a/deps/v8/test/cctest/compiler/test-code-assembler.cc
+++ b/deps/v8/test/cctest/compiler/test-code-assembler.cc
@@ -12,11 +12,9 @@ namespace v8 {
namespace internal {
namespace compiler {
-typedef CodeAssemblerTesterImpl<CodeAssembler> CodeAssemblerTester;
-
namespace {
-Node* SmiTag(CodeAssemblerTester& m, Node* value) {
+Node* SmiTag(CodeAssembler& m, Node* value) {
int32_t constant_value;
if (m.ToInt32Constant(value, constant_value) &&
Smi::IsValid(constant_value)) {
@@ -25,36 +23,47 @@ Node* SmiTag(CodeAssemblerTester& m, Node* value) {
return m.WordShl(value, m.IntPtrConstant(kSmiShiftSize + kSmiTagSize));
}
-Node* UndefinedConstant(CodeAssemblerTester& m) {
+Node* UndefinedConstant(CodeAssembler& m) {
return m.LoadRoot(Heap::kUndefinedValueRootIndex);
}
-Node* LoadObjectField(CodeAssemblerTester& m, Node* object, int offset,
+Node* SmiFromWord32(CodeAssembler& m, Node* value) {
+ value = m.ChangeInt32ToIntPtr(value);
+ return m.BitcastWordToTaggedSigned(
+ m.WordShl(value, kSmiShiftSize + kSmiTagSize));
+}
+
+Node* LoadObjectField(CodeAssembler& m, Node* object, int offset,
MachineType rep = MachineType::AnyTagged()) {
return m.Load(rep, object, m.IntPtrConstant(offset - kHeapObjectTag));
}
+Node* LoadMap(CodeAssembler& m, Node* object) {
+ return LoadObjectField(m, object, JSObject::kMapOffset);
+}
+
} // namespace
TEST(SimpleSmiReturn) {
Isolate* isolate(CcTest::InitIsolateOnce());
- VoidDescriptor descriptor(isolate);
- CodeAssemblerTester m(isolate, descriptor);
+ CodeAssemblerTester data(isolate);
+ CodeAssembler m(data.state());
m.Return(SmiTag(m, m.Int32Constant(37)));
- Handle<Code> code = m.GenerateCode();
- FunctionTester ft(descriptor, code);
+ Handle<Code> code = data.GenerateCode();
+ FunctionTester ft(code);
MaybeHandle<Object> result = ft.Call();
CHECK_EQ(37, Handle<Smi>::cast(result.ToHandleChecked())->value());
}
TEST(SimpleIntPtrReturn) {
Isolate* isolate(CcTest::InitIsolateOnce());
- VoidDescriptor descriptor(isolate);
- CodeAssemblerTester m(isolate, descriptor);
+ CodeAssemblerTester data(isolate);
+ CodeAssembler m(data.state());
int test;
- m.Return(m.IntPtrConstant(reinterpret_cast<intptr_t>(&test)));
- Handle<Code> code = m.GenerateCode();
- FunctionTester ft(descriptor, code);
+ m.Return(m.BitcastWordToTagged(
+ m.IntPtrConstant(reinterpret_cast<intptr_t>(&test))));
+ Handle<Code> code = data.GenerateCode();
+ FunctionTester ft(code);
MaybeHandle<Object> result = ft.Call();
CHECK_EQ(reinterpret_cast<intptr_t>(&test),
reinterpret_cast<intptr_t>(*result.ToHandleChecked()));
@@ -62,65 +71,65 @@ TEST(SimpleIntPtrReturn) {
TEST(SimpleDoubleReturn) {
Isolate* isolate(CcTest::InitIsolateOnce());
- VoidDescriptor descriptor(isolate);
- CodeAssemblerTester m(isolate, descriptor);
+ CodeAssemblerTester data(isolate);
+ CodeAssembler m(data.state());
m.Return(m.NumberConstant(0.5));
- Handle<Code> code = m.GenerateCode();
- FunctionTester ft(descriptor, code);
+ Handle<Code> code = data.GenerateCode();
+ FunctionTester ft(code);
MaybeHandle<Object> result = ft.Call();
CHECK_EQ(0.5, Handle<HeapNumber>::cast(result.ToHandleChecked())->value());
}
TEST(SimpleCallRuntime1Arg) {
Isolate* isolate(CcTest::InitIsolateOnce());
- VoidDescriptor descriptor(isolate);
- CodeAssemblerTester m(isolate, descriptor);
+ CodeAssemblerTester data(isolate);
+ CodeAssembler m(data.state());
Node* context = m.HeapConstant(Handle<Context>(isolate->native_context()));
Node* b = SmiTag(m, m.Int32Constant(0));
m.Return(m.CallRuntime(Runtime::kNumberToSmi, context, b));
- Handle<Code> code = m.GenerateCode();
- FunctionTester ft(descriptor, code);
+ Handle<Code> code = data.GenerateCode();
+ FunctionTester ft(code);
MaybeHandle<Object> result = ft.Call();
CHECK_EQ(0, Handle<Smi>::cast(result.ToHandleChecked())->value());
}
TEST(SimpleTailCallRuntime1Arg) {
Isolate* isolate(CcTest::InitIsolateOnce());
- VoidDescriptor descriptor(isolate);
- CodeAssemblerTester m(isolate, descriptor);
+ CodeAssemblerTester data(isolate);
+ CodeAssembler m(data.state());
Node* context = m.HeapConstant(Handle<Context>(isolate->native_context()));
Node* b = SmiTag(m, m.Int32Constant(0));
m.TailCallRuntime(Runtime::kNumberToSmi, context, b);
- Handle<Code> code = m.GenerateCode();
- FunctionTester ft(descriptor, code);
+ Handle<Code> code = data.GenerateCode();
+ FunctionTester ft(code);
MaybeHandle<Object> result = ft.Call();
CHECK_EQ(0, Handle<Smi>::cast(result.ToHandleChecked())->value());
}
TEST(SimpleCallRuntime2Arg) {
Isolate* isolate(CcTest::InitIsolateOnce());
- VoidDescriptor descriptor(isolate);
- CodeAssemblerTester m(isolate, descriptor);
+ CodeAssemblerTester data(isolate);
+ CodeAssembler m(data.state());
Node* context = m.HeapConstant(Handle<Context>(isolate->native_context()));
Node* a = SmiTag(m, m.Int32Constant(2));
Node* b = SmiTag(m, m.Int32Constant(4));
m.Return(m.CallRuntime(Runtime::kAdd, context, a, b));
- Handle<Code> code = m.GenerateCode();
- FunctionTester ft(descriptor, code);
+ Handle<Code> code = data.GenerateCode();
+ FunctionTester ft(code);
MaybeHandle<Object> result = ft.Call();
CHECK_EQ(6, Handle<Smi>::cast(result.ToHandleChecked())->value());
}
TEST(SimpleTailCallRuntime2Arg) {
Isolate* isolate(CcTest::InitIsolateOnce());
- VoidDescriptor descriptor(isolate);
- CodeAssemblerTester m(isolate, descriptor);
+ CodeAssemblerTester data(isolate);
+ CodeAssembler m(data.state());
Node* context = m.HeapConstant(Handle<Context>(isolate->native_context()));
Node* a = SmiTag(m, m.Int32Constant(2));
Node* b = SmiTag(m, m.Int32Constant(4));
m.TailCallRuntime(Runtime::kAdd, context, a, b);
- Handle<Code> code = m.GenerateCode();
- FunctionTester ft(descriptor, code);
+ Handle<Code> code = data.GenerateCode();
+ FunctionTester ft(code);
MaybeHandle<Object> result = ft.Call();
CHECK_EQ(6, Handle<Smi>::cast(result.ToHandleChecked())->value());
}
@@ -144,7 +153,8 @@ Handle<JSFunction> CreateSumAllArgumentsFunction(FunctionTester& ft) {
TEST(SimpleCallJSFunction0Arg) {
Isolate* isolate(CcTest::InitIsolateOnce());
const int kNumParams = 1;
- CodeAssemblerTester m(isolate, kNumParams);
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeAssembler m(data.state());
{
Node* function = m.Parameter(0);
Node* context = m.Parameter(kNumParams + 2);
@@ -155,7 +165,7 @@ TEST(SimpleCallJSFunction0Arg) {
Node* result = m.CallJS(callable, context, function, receiver);
m.Return(result);
}
- Handle<Code> code = m.GenerateCode();
+ Handle<Code> code = data.GenerateCode();
FunctionTester ft(code, kNumParams);
Handle<JSFunction> sum = CreateSumAllArgumentsFunction(ft);
@@ -166,7 +176,8 @@ TEST(SimpleCallJSFunction0Arg) {
TEST(SimpleCallJSFunction1Arg) {
Isolate* isolate(CcTest::InitIsolateOnce());
const int kNumParams = 2;
- CodeAssemblerTester m(isolate, kNumParams);
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeAssembler m(data.state());
{
Node* function = m.Parameter(0);
Node* context = m.Parameter(1);
@@ -178,7 +189,7 @@ TEST(SimpleCallJSFunction1Arg) {
Node* result = m.CallJS(callable, context, function, receiver, a);
m.Return(result);
}
- Handle<Code> code = m.GenerateCode();
+ Handle<Code> code = data.GenerateCode();
FunctionTester ft(code, kNumParams);
Handle<JSFunction> sum = CreateSumAllArgumentsFunction(ft);
@@ -189,7 +200,8 @@ TEST(SimpleCallJSFunction1Arg) {
TEST(SimpleCallJSFunction2Arg) {
Isolate* isolate(CcTest::InitIsolateOnce());
const int kNumParams = 2;
- CodeAssemblerTester m(isolate, kNumParams);
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeAssembler m(data.state());
{
Node* function = m.Parameter(0);
Node* context = m.Parameter(1);
@@ -202,7 +214,7 @@ TEST(SimpleCallJSFunction2Arg) {
Node* result = m.CallJS(callable, context, function, receiver, a, b);
m.Return(result);
}
- Handle<Code> code = m.GenerateCode();
+ Handle<Code> code = data.GenerateCode();
FunctionTester ft(code, kNumParams);
Handle<JSFunction> sum = CreateSumAllArgumentsFunction(ft);
@@ -212,10 +224,10 @@ TEST(SimpleCallJSFunction2Arg) {
TEST(VariableMerge1) {
Isolate* isolate(CcTest::InitIsolateOnce());
- VoidDescriptor descriptor(isolate);
- CodeAssemblerTester m(isolate, descriptor);
- CodeStubAssembler::Variable var1(&m, MachineRepresentation::kTagged);
- CodeStubAssembler::Label l1(&m), l2(&m), merge(&m);
+ CodeAssemblerTester data(isolate);
+ CodeAssembler m(data.state());
+ CodeAssemblerVariable var1(&m, MachineRepresentation::kTagged);
+ CodeAssemblerLabel l1(&m), l2(&m), merge(&m);
Node* temp = m.Int32Constant(0);
var1.Bind(temp);
m.Branch(m.Int32Constant(1), &l1, &l2);
@@ -231,10 +243,10 @@ TEST(VariableMerge1) {
TEST(VariableMerge2) {
Isolate* isolate(CcTest::InitIsolateOnce());
- VoidDescriptor descriptor(isolate);
- CodeAssemblerTester m(isolate, descriptor);
- CodeStubAssembler::Variable var1(&m, MachineRepresentation::kTagged);
- CodeStubAssembler::Label l1(&m), l2(&m), merge(&m);
+ CodeAssemblerTester data(isolate);
+ CodeAssembler m(data.state());
+ CodeAssemblerVariable var1(&m, MachineRepresentation::kTagged);
+ CodeAssemblerLabel l1(&m), l2(&m), merge(&m);
Node* temp = m.Int32Constant(0);
var1.Bind(temp);
m.Branch(m.Int32Constant(1), &l1, &l2);
@@ -252,11 +264,11 @@ TEST(VariableMerge2) {
TEST(VariableMerge3) {
Isolate* isolate(CcTest::InitIsolateOnce());
- VoidDescriptor descriptor(isolate);
- CodeAssemblerTester m(isolate, descriptor);
- CodeStubAssembler::Variable var1(&m, MachineRepresentation::kTagged);
- CodeStubAssembler::Variable var2(&m, MachineRepresentation::kTagged);
- CodeStubAssembler::Label l1(&m), l2(&m), merge(&m);
+ CodeAssemblerTester data(isolate);
+ CodeAssembler m(data.state());
+ CodeAssemblerVariable var1(&m, MachineRepresentation::kTagged);
+ CodeAssemblerVariable var2(&m, MachineRepresentation::kTagged);
+ CodeAssemblerLabel l1(&m), l2(&m), merge(&m);
Node* temp = m.Int32Constant(0);
var1.Bind(temp);
var2.Bind(temp);
@@ -277,10 +289,10 @@ TEST(VariableMerge3) {
TEST(VariableMergeBindFirst) {
Isolate* isolate(CcTest::InitIsolateOnce());
- VoidDescriptor descriptor(isolate);
- CodeAssemblerTester m(isolate, descriptor);
- CodeStubAssembler::Variable var1(&m, MachineRepresentation::kTagged);
- CodeStubAssembler::Label l1(&m), l2(&m), merge(&m, &var1), end(&m);
+ CodeAssemblerTester data(isolate);
+ CodeAssembler m(data.state());
+ CodeAssemblerVariable var1(&m, MachineRepresentation::kTagged);
+ CodeAssemblerLabel l1(&m), l2(&m), merge(&m, &var1), end(&m);
Node* temp = m.Int32Constant(0);
var1.Bind(temp);
m.Branch(m.Int32Constant(1), &l1, &l2);
@@ -303,11 +315,11 @@ TEST(VariableMergeBindFirst) {
TEST(VariableMergeSwitch) {
Isolate* isolate(CcTest::InitIsolateOnce());
- VoidDescriptor descriptor(isolate);
- CodeAssemblerTester m(isolate, descriptor);
- CodeStubAssembler::Variable var1(&m, MachineRepresentation::kTagged);
- CodeStubAssembler::Label l1(&m), l2(&m), default_label(&m);
- CodeStubAssembler::Label* labels[] = {&l1, &l2};
+ CodeAssemblerTester data(isolate);
+ CodeAssembler m(data.state());
+ CodeAssemblerVariable var1(&m, MachineRepresentation::kTagged);
+ CodeAssemblerLabel l1(&m), l2(&m), default_label(&m);
+ CodeAssemblerLabel* labels[] = {&l1, &l2};
int32_t values[] = {1, 2};
Node* temp = m.Int32Constant(0);
var1.Bind(temp);
@@ -325,22 +337,22 @@ TEST(VariableMergeSwitch) {
TEST(SplitEdgeBranchMerge) {
Isolate* isolate(CcTest::InitIsolateOnce());
- VoidDescriptor descriptor(isolate);
- CodeAssemblerTester m(isolate, descriptor);
- CodeStubAssembler::Label l1(&m), merge(&m);
+ CodeAssemblerTester data(isolate);
+ CodeAssembler m(data.state());
+ CodeAssemblerLabel l1(&m), merge(&m);
m.Branch(m.Int32Constant(1), &l1, &merge);
m.Bind(&l1);
m.Goto(&merge);
m.Bind(&merge);
- USE(m.GenerateCode());
+ USE(data.GenerateCode());
}
TEST(SplitEdgeSwitchMerge) {
Isolate* isolate(CcTest::InitIsolateOnce());
- VoidDescriptor descriptor(isolate);
- CodeAssemblerTester m(isolate, descriptor);
- CodeStubAssembler::Label l1(&m), l2(&m), l3(&m), default_label(&m);
- CodeStubAssembler::Label* labels[] = {&l1, &l2};
+ CodeAssemblerTester data(isolate);
+ CodeAssembler m(data.state());
+ CodeAssemblerLabel l1(&m), l2(&m), l3(&m), default_label(&m);
+ CodeAssemblerLabel* labels[] = {&l1, &l2};
int32_t values[] = {1, 2};
m.Branch(m.Int32Constant(1), &l3, &l1);
m.Bind(&l3);
@@ -350,13 +362,13 @@ TEST(SplitEdgeSwitchMerge) {
m.Bind(&l2);
m.Goto(&default_label);
m.Bind(&default_label);
- USE(m.GenerateCode());
+ USE(data.GenerateCode());
}
TEST(TestToConstant) {
Isolate* isolate(CcTest::InitIsolateOnce());
- VoidDescriptor descriptor(isolate);
- CodeAssemblerTester m(isolate, descriptor);
+ CodeAssemblerTester data(isolate);
+ CodeAssembler m(data.state());
int32_t value32;
int64_t value64;
Node* a = m.Int32Constant(5);
@@ -381,36 +393,35 @@ TEST(TestToConstant) {
}
TEST(DeferredCodePhiHints) {
- typedef compiler::Node Node;
- typedef CodeStubAssembler::Label Label;
- typedef CodeStubAssembler::Variable Variable;
+ typedef CodeAssemblerLabel Label;
+ typedef CodeAssemblerVariable Variable;
Isolate* isolate(CcTest::InitIsolateOnce());
- VoidDescriptor descriptor(isolate);
- CodeAssemblerTester m(isolate, descriptor);
+ CodeAssemblerTester data(isolate);
+ CodeAssembler m(data.state());
Label block1(&m, Label::kDeferred);
m.Goto(&block1);
m.Bind(&block1);
{
Variable var_object(&m, MachineRepresentation::kTagged);
Label loop(&m, &var_object);
- var_object.Bind(m.IntPtrConstant(0));
+ var_object.Bind(m.SmiConstant(0));
m.Goto(&loop);
m.Bind(&loop);
{
- Node* map = LoadObjectField(m, var_object.value(), JSObject::kMapOffset);
+ Node* map = LoadMap(m, var_object.value());
var_object.Bind(map);
m.Goto(&loop);
}
}
- CHECK(!m.GenerateCode().is_null());
+ CHECK(!data.GenerateCode().is_null());
}
TEST(TestOutOfScopeVariable) {
- typedef CodeStubAssembler::Label Label;
- typedef CodeStubAssembler::Variable Variable;
+ typedef CodeAssemblerLabel Label;
+ typedef CodeAssemblerVariable Variable;
Isolate* isolate(CcTest::InitIsolateOnce());
- VoidDescriptor descriptor(isolate);
- CodeAssemblerTester m(isolate, descriptor);
+ CodeAssemblerTester data(isolate);
+ CodeAssembler m(data.state());
Label block1(&m);
Label block2(&m);
Label block3(&m);
@@ -431,7 +442,136 @@ TEST(TestOutOfScopeVariable) {
m.Goto(&block1);
}
m.Bind(&block1);
- CHECK(!m.GenerateCode().is_null());
+ CHECK(!data.GenerateCode().is_null());
+}
+
+TEST(GotoIfException) {
+ typedef CodeAssemblerLabel Label;
+ typedef CodeAssemblerVariable Variable;
+ Isolate* isolate(CcTest::InitIsolateOnce());
+
+ const int kNumParams = 1;
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeAssembler m(data.state());
+
+ Node* context = m.HeapConstant(Handle<Context>(isolate->native_context()));
+ Node* to_string_tag =
+ m.HeapConstant(isolate->factory()->to_string_tag_symbol());
+ Variable exception(&m, MachineRepresentation::kTagged);
+
+ Label exception_handler(&m);
+ Callable to_string = CodeFactory::ToString(isolate);
+ Node* string = m.CallStub(to_string, context, to_string_tag);
+ m.GotoIfException(string, &exception_handler, &exception);
+ m.Return(string);
+
+ m.Bind(&exception_handler);
+ m.Return(exception.value());
+
+ Handle<Code> code = data.GenerateCode();
+ CHECK(!code.is_null());
+
+ FunctionTester ft(code, kNumParams);
+ Handle<Object> result = ft.Call().ToHandleChecked();
+
+ // Should be a TypeError.
+ CHECK(result->IsJSObject());
+
+ Handle<Object> constructor =
+ Object::GetPropertyOrElement(result,
+ isolate->factory()->constructor_string())
+ .ToHandleChecked();
+ CHECK(constructor->SameValue(*isolate->type_error_function()));
+}
+
+TEST(GotoIfExceptionMultiple) {
+ typedef CodeAssemblerLabel Label;
+ typedef CodeAssemblerVariable Variable;
+ Isolate* isolate(CcTest::InitIsolateOnce());
+
+ const int kNumParams = 4; // receiver, first, second, third
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeAssembler m(data.state());
+
+ Node* context = m.HeapConstant(Handle<Context>(isolate->native_context()));
+ Node* first_value = m.Parameter(0);
+ Node* second_value = m.Parameter(1);
+ Node* third_value = m.Parameter(2);
+
+ Label exception_handler1(&m);
+ Label exception_handler2(&m);
+ Label exception_handler3(&m);
+ Variable return_value(&m, MachineRepresentation::kWord32);
+ Variable error(&m, MachineRepresentation::kTagged);
+
+ return_value.Bind(m.Int32Constant(0));
+
+ // try { return ToString(param1) } catch (e) { ... }
+ Callable to_string = CodeFactory::ToString(isolate);
+ Node* string = m.CallStub(to_string, context, first_value);
+ m.GotoIfException(string, &exception_handler1, &error);
+ m.Return(string);
+
+ // try { ToString(param2); return 7 } catch (e) { ... }
+ m.Bind(&exception_handler1);
+ return_value.Bind(m.Int32Constant(7));
+ error.Bind(UndefinedConstant(m));
+ string = m.CallStub(to_string, context, second_value);
+ m.GotoIfException(string, &exception_handler2, &error);
+ m.Return(SmiFromWord32(m, return_value.value()));
+
+ // try { ToString(param3); return 7 & ~2; } catch (e) { return e; }
+ m.Bind(&exception_handler2);
+ // Return returnValue & ~2
+ error.Bind(UndefinedConstant(m));
+ string = m.CallStub(to_string, context, third_value);
+ m.GotoIfException(string, &exception_handler3, &error);
+ m.Return(SmiFromWord32(
+ m, m.Word32And(return_value.value(),
+ m.Word32Xor(m.Int32Constant(2), m.Int32Constant(-1)))));
+
+ m.Bind(&exception_handler3);
+ m.Return(error.value());
+
+ Handle<Code> code = data.GenerateCode();
+ CHECK(!code.is_null());
+
+ FunctionTester ft(code, kNumParams);
+
+ Handle<Object> result;
+ // First handler does not throw, returns result of first value.
+ result = ft.Call(isolate->factory()->undefined_value(),
+ isolate->factory()->to_string_tag_symbol())
+ .ToHandleChecked();
+ CHECK(String::cast(*result)->IsOneByteEqualTo(OneByteVector("undefined")));
+
+ // First handler returns a number.
+ result = ft.Call(isolate->factory()->to_string_tag_symbol(),
+ isolate->factory()->undefined_value())
+ .ToHandleChecked();
+ CHECK_EQ(7, Smi::cast(*result)->value());
+
+ // First handler throws, second handler returns a number.
+ result = ft.Call(isolate->factory()->to_string_tag_symbol(),
+ isolate->factory()->to_primitive_symbol())
+ .ToHandleChecked();
+ CHECK_EQ(7 & ~2, Smi::cast(*result)->value());
+
+ // First handler throws, second handler throws, third handler returns thrown
+ // value.
+ result = ft.Call(isolate->factory()->to_string_tag_symbol(),
+ isolate->factory()->to_primitive_symbol(),
+ isolate->factory()->unscopables_symbol())
+ .ToHandleChecked();
+
+ // Should be a TypeError.
+ CHECK(result->IsJSObject());
+
+ Handle<Object> constructor =
+ Object::GetPropertyOrElement(result,
+ isolate->factory()->constructor_string())
+ .ToHandleChecked();
+ CHECK(constructor->SameValue(*isolate->type_error_function()));
}
} // namespace compiler
diff --git a/deps/v8/test/cctest/compiler/test-js-context-specialization.cc b/deps/v8/test/cctest/compiler/test-js-context-specialization.cc
index 023ef483ea..d8122c4fdb 100644
--- a/deps/v8/test/cctest/compiler/test-js-context-specialization.cc
+++ b/deps/v8/test/cctest/compiler/test-js-context-specialization.cc
@@ -18,7 +18,7 @@ namespace compiler {
class ContextSpecializationTester : public HandleAndZoneScope {
public:
- ContextSpecializationTester()
+ explicit ContextSpecializationTester(MaybeHandle<Context> context)
: graph_(new (main_zone()) Graph(main_zone())),
common_(main_zone()),
javascript_(main_zone()),
@@ -27,7 +27,7 @@ class ContextSpecializationTester : public HandleAndZoneScope {
jsgraph_(main_isolate(), graph(), common(), &javascript_, &simplified_,
&machine_),
reducer_(main_zone(), graph()),
- spec_(&reducer_, jsgraph(), MaybeHandle<Context>()) {}
+ spec_(&reducer_, jsgraph(), context) {}
JSContextSpecialization* spec() { return &spec_; }
Factory* factory() { return main_isolate()->factory(); }
@@ -37,6 +37,13 @@ class ContextSpecializationTester : public HandleAndZoneScope {
JSGraph* jsgraph() { return &jsgraph_; }
Graph* graph() { return graph_; }
+ void CheckChangesToValue(Node* node, Handle<HeapObject> expected_value);
+ void CheckContextInputAndDepthChanges(
+ Node* node, Handle<Context> expected_new_context_object,
+ size_t expected_new_depth);
+ void CheckContextInputAndDepthChanges(Node* node, Node* expected_new_context,
+ size_t expected_new_depth);
+
private:
Graph* graph_;
CommonOperatorBuilder common_;
@@ -48,9 +55,52 @@ class ContextSpecializationTester : public HandleAndZoneScope {
JSContextSpecialization spec_;
};
+void ContextSpecializationTester::CheckChangesToValue(
+ Node* node, Handle<HeapObject> expected_value) {
+ Reduction r = spec()->Reduce(node);
+ CHECK(r.Changed());
+ HeapObjectMatcher match(r.replacement());
+ CHECK(match.HasValue());
+ CHECK_EQ(*match.Value(), *expected_value);
+}
+
+void ContextSpecializationTester::CheckContextInputAndDepthChanges(
+ Node* node, Handle<Context> expected_new_context_object,
+ size_t expected_new_depth) {
+ ContextAccess access = OpParameter<ContextAccess>(node);
+ Reduction r = spec()->Reduce(node);
+ CHECK(r.Changed());
+
+ Node* new_context = NodeProperties::GetContextInput(r.replacement());
+ CHECK_EQ(IrOpcode::kHeapConstant, new_context->opcode());
+ HeapObjectMatcher match(new_context);
+ CHECK_EQ(*match.Value(), *expected_new_context_object);
+
+ ContextAccess new_access = OpParameter<ContextAccess>(r.replacement());
+ CHECK_EQ(new_access.depth(), expected_new_depth);
+ CHECK_EQ(new_access.index(), access.index());
+ CHECK_EQ(new_access.immutable(), access.immutable());
+}
+
+void ContextSpecializationTester::CheckContextInputAndDepthChanges(
+ Node* node, Node* expected_new_context, size_t expected_new_depth) {
+ ContextAccess access = OpParameter<ContextAccess>(node);
+ Reduction r = spec()->Reduce(node);
+ CHECK(r.Changed());
+
+ Node* new_context = NodeProperties::GetContextInput(r.replacement());
+ CHECK_EQ(new_context, expected_new_context);
-TEST(ReduceJSLoadContext) {
- ContextSpecializationTester t;
+ ContextAccess new_access = OpParameter<ContextAccess>(r.replacement());
+ CHECK_EQ(new_access.depth(), expected_new_depth);
+ CHECK_EQ(new_access.index(), access.index());
+ CHECK_EQ(new_access.immutable(), access.immutable());
+}
+
+static const int slot_index = Context::NATIVE_CONTEXT_INDEX;
+
+TEST(ReduceJSLoadContext0) {
+ ContextSpecializationTester t((MaybeHandle<Context>()));
Node* start = t.graph()->NewNode(t.common()->Start(0));
t.graph()->SetStart(start);
@@ -72,7 +122,7 @@ TEST(ReduceJSLoadContext) {
{
// Mutable slot, constant context, depth = 0 => do nothing.
Node* load = t.graph()->NewNode(t.javascript()->LoadContext(0, 0, false),
- const_context, const_context, start);
+ const_context, start);
Reduction r = t.spec()->Reduce(load);
CHECK(!r.Changed());
}
@@ -80,7 +130,7 @@ TEST(ReduceJSLoadContext) {
{
// Mutable slot, non-constant context, depth = 0 => do nothing.
Node* load = t.graph()->NewNode(t.javascript()->LoadContext(0, 0, false),
- param_context, param_context, start);
+ param_context, start);
Reduction r = t.spec()->Reduce(load);
CHECK(!r.Changed());
}
@@ -89,10 +139,10 @@ TEST(ReduceJSLoadContext) {
// Mutable slot, constant context, depth > 0 => fold-in parent context.
Node* load = t.graph()->NewNode(
t.javascript()->LoadContext(2, Context::GLOBAL_EVAL_FUN_INDEX, false),
- deep_const_context, deep_const_context, start);
+ deep_const_context, start);
Reduction r = t.spec()->Reduce(load);
CHECK(r.Changed());
- Node* new_context_input = NodeProperties::GetValueInput(r.replacement(), 0);
+ Node* new_context_input = NodeProperties::GetContextInput(r.replacement());
CHECK_EQ(IrOpcode::kHeapConstant, new_context_input->opcode());
HeapObjectMatcher match(new_context_input);
CHECK_EQ(*native, *match.Value());
@@ -105,7 +155,7 @@ TEST(ReduceJSLoadContext) {
{
// Immutable slot, constant context, depth = 0 => specialize.
Node* load = t.graph()->NewNode(t.javascript()->LoadContext(0, slot, true),
- const_context, const_context, start);
+ const_context, start);
Reduction r = t.spec()->Reduce(load);
CHECK(r.Changed());
CHECK(r.replacement() != load);
@@ -114,14 +164,239 @@ TEST(ReduceJSLoadContext) {
CHECK(match.HasValue());
CHECK_EQ(*expected, *match.Value());
}
+}
+
+TEST(ReduceJSLoadContext1) {
+ // The graph's context chain ends in the incoming context parameter:
+ //
+ // context2 <-- context1 <-- context0 (= Parameter(0))
+
+ ContextSpecializationTester t((MaybeHandle<Context>()));
+
+ Node* start = t.graph()->NewNode(t.common()->Start(0));
+ t.graph()->SetStart(start);
+ Node* undefined = t.jsgraph()->Constant(t.factory()->undefined_value());
+ const i::compiler::Operator* create_function_context =
+ t.javascript()->CreateFunctionContext(42, FUNCTION_SCOPE);
+
+ Node* context0 = t.graph()->NewNode(t.common()->Parameter(0), start);
+ Node* context1 = t.graph()->NewNode(create_function_context, undefined,
+ context0, start, start);
+ Node* context2 = t.graph()->NewNode(create_function_context, undefined,
+ context1, start, start);
+
+ {
+ Node* load = t.graph()->NewNode(
+ t.javascript()->LoadContext(0, slot_index, false), context2, start);
+ CHECK(!t.spec()->Reduce(load).Changed());
+ }
+
+ {
+ Node* load = t.graph()->NewNode(
+ t.javascript()->LoadContext(0, slot_index, true), context2, start);
+ CHECK(!t.spec()->Reduce(load).Changed());
+ }
- // TODO(titzer): test with other kinds of contexts, e.g. a function context.
- // TODO(sigurds): test that loads below create context are not optimized
+ {
+ Node* load = t.graph()->NewNode(
+ t.javascript()->LoadContext(1, slot_index, false), context2, start);
+ t.CheckContextInputAndDepthChanges(load, context1, 0);
+ }
+
+ {
+ Node* load = t.graph()->NewNode(
+ t.javascript()->LoadContext(1, slot_index, true), context2, start);
+ t.CheckContextInputAndDepthChanges(load, context1, 0);
+ }
+
+ {
+ Node* load = t.graph()->NewNode(
+ t.javascript()->LoadContext(2, slot_index, false), context2, start);
+ t.CheckContextInputAndDepthChanges(load, context0, 0);
+ }
+
+ {
+ Node* load = t.graph()->NewNode(
+ t.javascript()->LoadContext(2, slot_index, true), context2, start);
+ t.CheckContextInputAndDepthChanges(load, context0, 0);
+ }
+
+ {
+ Node* load = t.graph()->NewNode(
+ t.javascript()->LoadContext(3, slot_index, false), context2, start);
+ t.CheckContextInputAndDepthChanges(load, context0, 1);
+ }
+
+ {
+ Node* load = t.graph()->NewNode(
+ t.javascript()->LoadContext(3, slot_index, true), context2, start);
+ t.CheckContextInputAndDepthChanges(load, context0, 1);
+ }
}
+TEST(ReduceJSLoadContext2) {
+ // The graph's context chain ends in a constant context (context_object1),
+ // which has has another outer context (context_object0).
+ //
+ // context2 <-- context1 <-- context0 (= HeapConstant(context_object1))
+ // context_object1 <~~ context_object0
-TEST(ReduceJSStoreContext) {
- ContextSpecializationTester t;
+ ContextSpecializationTester t((MaybeHandle<Context>()));
+
+ Node* start = t.graph()->NewNode(t.common()->Start(0));
+ t.graph()->SetStart(start);
+ Node* undefined = t.jsgraph()->Constant(t.factory()->undefined_value());
+ const i::compiler::Operator* create_function_context =
+ t.javascript()->CreateFunctionContext(42, FUNCTION_SCOPE);
+
+ Handle<HeapObject> slot_value0 = t.factory()->InternalizeUtf8String("0");
+ Handle<HeapObject> slot_value1 = t.factory()->InternalizeUtf8String("1");
+
+ Handle<Context> context_object0 = t.factory()->NewNativeContext();
+ Handle<Context> context_object1 = t.factory()->NewNativeContext();
+ context_object1->set_previous(*context_object0);
+ context_object0->set(slot_index, *slot_value0);
+ context_object1->set(slot_index, *slot_value1);
+
+ Node* context0 = t.jsgraph()->Constant(context_object1);
+ Node* context1 = t.graph()->NewNode(create_function_context, undefined,
+ context0, start, start);
+ Node* context2 = t.graph()->NewNode(create_function_context, undefined,
+ context1, start, start);
+
+ {
+ Node* load = t.graph()->NewNode(
+ t.javascript()->LoadContext(0, slot_index, false), context2, start);
+ CHECK(!t.spec()->Reduce(load).Changed());
+ }
+
+ {
+ Node* load = t.graph()->NewNode(
+ t.javascript()->LoadContext(0, slot_index, true), context2, start);
+ CHECK(!t.spec()->Reduce(load).Changed());
+ }
+
+ {
+ Node* load = t.graph()->NewNode(
+ t.javascript()->LoadContext(1, slot_index, false), context2, start);
+ t.CheckContextInputAndDepthChanges(load, context1, 0);
+ }
+
+ {
+ Node* load = t.graph()->NewNode(
+ t.javascript()->LoadContext(1, slot_index, true), context2, start);
+ t.CheckContextInputAndDepthChanges(load, context1, 0);
+ }
+
+ {
+ Node* load = t.graph()->NewNode(
+ t.javascript()->LoadContext(2, slot_index, false), context2, start);
+ t.CheckContextInputAndDepthChanges(load, context0, 0);
+ }
+
+ {
+ Node* load = t.graph()->NewNode(
+ t.javascript()->LoadContext(2, slot_index, true), context2, start);
+ t.CheckChangesToValue(load, slot_value1);
+ }
+
+ {
+ Node* load = t.graph()->NewNode(
+ t.javascript()->LoadContext(3, slot_index, false), context2, start);
+ t.CheckContextInputAndDepthChanges(load, context_object0, 0);
+ }
+
+ {
+ Node* load = t.graph()->NewNode(
+ t.javascript()->LoadContext(3, slot_index, true), context2, start);
+ t.CheckChangesToValue(load, slot_value0);
+ }
+}
+
+TEST(ReduceJSLoadContext3) {
+ // Like in ReduceJSLoadContext1, the graph's context chain ends in the
+ // incoming context parameter. However, this time we provide a concrete
+ // context for this parameter as the "specialization context". We choose
+ // context_object2 from ReduceJSLoadContext2 for this, so almost all test
+ // expectations are the same as in ReduceJSLoadContext2.
+
+ HandleAndZoneScope handle_zone_scope;
+ auto factory = handle_zone_scope.main_isolate()->factory();
+
+ Handle<HeapObject> slot_value0 = factory->InternalizeUtf8String("0");
+ Handle<HeapObject> slot_value1 = factory->InternalizeUtf8String("1");
+
+ Handle<Context> context_object0 = factory->NewNativeContext();
+ Handle<Context> context_object1 = factory->NewNativeContext();
+ context_object1->set_previous(*context_object0);
+ context_object0->set(slot_index, *slot_value0);
+ context_object1->set(slot_index, *slot_value1);
+
+ ContextSpecializationTester t(context_object1);
+
+ Node* start = t.graph()->NewNode(t.common()->Start(2));
+ t.graph()->SetStart(start);
+ Node* undefined = t.jsgraph()->Constant(t.factory()->undefined_value());
+ const i::compiler::Operator* create_function_context =
+ t.javascript()->CreateFunctionContext(42, FUNCTION_SCOPE);
+
+ Node* context0 = t.graph()->NewNode(t.common()->Parameter(0), start);
+ Node* context1 = t.graph()->NewNode(create_function_context, undefined,
+ context0, start, start);
+ Node* context2 = t.graph()->NewNode(create_function_context, undefined,
+ context1, start, start);
+
+ {
+ Node* load = t.graph()->NewNode(
+ t.javascript()->LoadContext(0, slot_index, false), context2, start);
+ CHECK(!t.spec()->Reduce(load).Changed());
+ }
+
+ {
+ Node* load = t.graph()->NewNode(
+ t.javascript()->LoadContext(0, slot_index, true), context2, start);
+ CHECK(!t.spec()->Reduce(load).Changed());
+ }
+
+ {
+ Node* load = t.graph()->NewNode(
+ t.javascript()->LoadContext(1, slot_index, false), context2, start);
+ t.CheckContextInputAndDepthChanges(load, context1, 0);
+ }
+
+ {
+ Node* load = t.graph()->NewNode(
+ t.javascript()->LoadContext(1, slot_index, true), context2, start);
+ t.CheckContextInputAndDepthChanges(load, context1, 0);
+ }
+
+ {
+ Node* load = t.graph()->NewNode(
+ t.javascript()->LoadContext(2, slot_index, false), context2, start);
+ t.CheckContextInputAndDepthChanges(load, context_object1, 0);
+ }
+
+ {
+ Node* load = t.graph()->NewNode(
+ t.javascript()->LoadContext(2, slot_index, true), context2, start);
+ t.CheckChangesToValue(load, slot_value1);
+ }
+
+ {
+ Node* load = t.graph()->NewNode(
+ t.javascript()->LoadContext(3, slot_index, false), context2, start);
+ t.CheckContextInputAndDepthChanges(load, context_object0, 0);
+ }
+
+ {
+ Node* load = t.graph()->NewNode(
+ t.javascript()->LoadContext(3, slot_index, true), context2, start);
+ t.CheckChangesToValue(load, slot_value0);
+ }
+}
+
+TEST(ReduceJSStoreContext0) {
+ ContextSpecializationTester t((MaybeHandle<Context>()));
Node* start = t.graph()->NewNode(t.common()->Start(0));
t.graph()->SetStart(start);
@@ -142,27 +417,24 @@ TEST(ReduceJSStoreContext) {
{
// Mutable slot, constant context, depth = 0 => do nothing.
- Node* load =
- t.graph()->NewNode(t.javascript()->StoreContext(0, 0), const_context,
- const_context, const_context, start, start);
+ Node* load = t.graph()->NewNode(t.javascript()->StoreContext(0, 0),
+ const_context, const_context, start, start);
Reduction r = t.spec()->Reduce(load);
CHECK(!r.Changed());
}
{
// Mutable slot, non-constant context, depth = 0 => do nothing.
- Node* load =
- t.graph()->NewNode(t.javascript()->StoreContext(0, 0), param_context,
- param_context, const_context, start, start);
+ Node* load = t.graph()->NewNode(t.javascript()->StoreContext(0, 0),
+ param_context, param_context, start, start);
Reduction r = t.spec()->Reduce(load);
CHECK(!r.Changed());
}
{
// Immutable slot, constant context, depth = 0 => do nothing.
- Node* load =
- t.graph()->NewNode(t.javascript()->StoreContext(0, slot), const_context,
- const_context, const_context, start, start);
+ Node* load = t.graph()->NewNode(t.javascript()->StoreContext(0, slot),
+ const_context, const_context, start, start);
Reduction r = t.spec()->Reduce(load);
CHECK(!r.Changed());
}
@@ -171,10 +443,10 @@ TEST(ReduceJSStoreContext) {
// Mutable slot, constant context, depth > 0 => fold-in parent context.
Node* load = t.graph()->NewNode(
t.javascript()->StoreContext(2, Context::GLOBAL_EVAL_FUN_INDEX),
- deep_const_context, deep_const_context, const_context, start, start);
+ deep_const_context, deep_const_context, start, start);
Reduction r = t.spec()->Reduce(load);
CHECK(r.Changed());
- Node* new_context_input = NodeProperties::GetValueInput(r.replacement(), 0);
+ Node* new_context_input = NodeProperties::GetContextInput(r.replacement());
CHECK_EQ(IrOpcode::kHeapConstant, new_context_input->opcode());
HeapObjectMatcher match(new_context_input);
CHECK_EQ(*native, *match.Value());
@@ -185,6 +457,158 @@ TEST(ReduceJSStoreContext) {
}
}
+TEST(ReduceJSStoreContext1) {
+ ContextSpecializationTester t((MaybeHandle<Context>()));
+
+ Node* start = t.graph()->NewNode(t.common()->Start(0));
+ t.graph()->SetStart(start);
+ Node* undefined = t.jsgraph()->Constant(t.factory()->undefined_value());
+ const i::compiler::Operator* create_function_context =
+ t.javascript()->CreateFunctionContext(42, FUNCTION_SCOPE);
+
+ Node* context0 = t.graph()->NewNode(t.common()->Parameter(0), start);
+ Node* context1 = t.graph()->NewNode(create_function_context, undefined,
+ context0, start, start);
+ Node* context2 = t.graph()->NewNode(create_function_context, undefined,
+ context1, start, start);
+
+ {
+ Node* store =
+ t.graph()->NewNode(t.javascript()->StoreContext(0, slot_index),
+ context2, context2, start, start);
+ CHECK(!t.spec()->Reduce(store).Changed());
+ }
+
+ {
+ Node* store =
+ t.graph()->NewNode(t.javascript()->StoreContext(1, slot_index),
+ context2, context2, start, start);
+ t.CheckContextInputAndDepthChanges(store, context1, 0);
+ }
+
+ {
+ Node* store =
+ t.graph()->NewNode(t.javascript()->StoreContext(2, slot_index),
+ context2, context2, start, start);
+ t.CheckContextInputAndDepthChanges(store, context0, 0);
+ }
+
+ {
+ Node* store =
+ t.graph()->NewNode(t.javascript()->StoreContext(3, slot_index),
+ context2, context2, start, start);
+ t.CheckContextInputAndDepthChanges(store, context0, 1);
+ }
+}
+
+TEST(ReduceJSStoreContext2) {
+ ContextSpecializationTester t((MaybeHandle<Context>()));
+
+ Node* start = t.graph()->NewNode(t.common()->Start(0));
+ t.graph()->SetStart(start);
+ Node* undefined = t.jsgraph()->Constant(t.factory()->undefined_value());
+ const i::compiler::Operator* create_function_context =
+ t.javascript()->CreateFunctionContext(42, FUNCTION_SCOPE);
+
+ Handle<HeapObject> slot_value0 = t.factory()->InternalizeUtf8String("0");
+ Handle<HeapObject> slot_value1 = t.factory()->InternalizeUtf8String("1");
+
+ Handle<Context> context_object0 = t.factory()->NewNativeContext();
+ Handle<Context> context_object1 = t.factory()->NewNativeContext();
+ context_object1->set_previous(*context_object0);
+ context_object0->set(slot_index, *slot_value0);
+ context_object1->set(slot_index, *slot_value1);
+
+ Node* context0 = t.jsgraph()->Constant(context_object1);
+ Node* context1 = t.graph()->NewNode(create_function_context, undefined,
+ context0, start, start);
+ Node* context2 = t.graph()->NewNode(create_function_context, undefined,
+ context1, start, start);
+
+ {
+ Node* store =
+ t.graph()->NewNode(t.javascript()->StoreContext(0, slot_index),
+ context2, context2, start, start);
+ CHECK(!t.spec()->Reduce(store).Changed());
+ }
+
+ {
+ Node* store =
+ t.graph()->NewNode(t.javascript()->StoreContext(1, slot_index),
+ context2, context2, start, start);
+ t.CheckContextInputAndDepthChanges(store, context1, 0);
+ }
+
+ {
+ Node* store =
+ t.graph()->NewNode(t.javascript()->StoreContext(2, slot_index),
+ context2, context2, start, start);
+ t.CheckContextInputAndDepthChanges(store, context0, 0);
+ }
+
+ {
+ Node* store =
+ t.graph()->NewNode(t.javascript()->StoreContext(3, slot_index),
+ context2, context2, start, start);
+ t.CheckContextInputAndDepthChanges(store, context_object0, 0);
+ }
+}
+
+TEST(ReduceJSStoreContext3) {
+ HandleAndZoneScope handle_zone_scope;
+ auto factory = handle_zone_scope.main_isolate()->factory();
+
+ Handle<HeapObject> slot_value0 = factory->InternalizeUtf8String("0");
+ Handle<HeapObject> slot_value1 = factory->InternalizeUtf8String("1");
+
+ Handle<Context> context_object0 = factory->NewNativeContext();
+ Handle<Context> context_object1 = factory->NewNativeContext();
+ context_object1->set_previous(*context_object0);
+ context_object0->set(slot_index, *slot_value0);
+ context_object1->set(slot_index, *slot_value1);
+
+ ContextSpecializationTester t(context_object1);
+
+ Node* start = t.graph()->NewNode(t.common()->Start(2));
+ t.graph()->SetStart(start);
+ Node* undefined = t.jsgraph()->Constant(t.factory()->undefined_value());
+ const i::compiler::Operator* create_function_context =
+ t.javascript()->CreateFunctionContext(42, FUNCTION_SCOPE);
+
+ Node* context0 = t.graph()->NewNode(t.common()->Parameter(0), start);
+ Node* context1 = t.graph()->NewNode(create_function_context, undefined,
+ context0, start, start);
+ Node* context2 = t.graph()->NewNode(create_function_context, undefined,
+ context1, start, start);
+
+ {
+ Node* store =
+ t.graph()->NewNode(t.javascript()->StoreContext(0, slot_index),
+ context2, context2, start, start);
+ CHECK(!t.spec()->Reduce(store).Changed());
+ }
+
+ {
+ Node* store =
+ t.graph()->NewNode(t.javascript()->StoreContext(1, slot_index),
+ context2, context2, start, start);
+ t.CheckContextInputAndDepthChanges(store, context1, 0);
+ }
+
+ {
+ Node* store =
+ t.graph()->NewNode(t.javascript()->StoreContext(2, slot_index),
+ context2, context2, start, start);
+ t.CheckContextInputAndDepthChanges(store, context_object1, 0);
+ }
+
+ {
+ Node* store =
+ t.graph()->NewNode(t.javascript()->StoreContext(3, slot_index),
+ context2, context2, start, start);
+ t.CheckContextInputAndDepthChanges(store, context_object0, 0);
+ }
+}
TEST(SpecializeJSFunction_ToConstant1) {
FunctionTester T(
diff --git a/deps/v8/test/cctest/compiler/test-js-typed-lowering.cc b/deps/v8/test/cctest/compiler/test-js-typed-lowering.cc
index f504e549fd..606f338052 100644
--- a/deps/v8/test/cctest/compiler/test-js-typed-lowering.cc
+++ b/deps/v8/test/cctest/compiler/test-js-typed-lowering.cc
@@ -77,9 +77,12 @@ class JSTypedLoweringTester : public HandleAndZoneScope {
}
Node* EmptyFrameState(Node* context) {
- Node* parameters = graph.NewNode(common.StateValues(0));
- Node* locals = graph.NewNode(common.StateValues(0));
- Node* stack = graph.NewNode(common.StateValues(0));
+ Node* parameters =
+ graph.NewNode(common.StateValues(0, SparseInputMask::Dense()));
+ Node* locals =
+ graph.NewNode(common.StateValues(0, SparseInputMask::Dense()));
+ Node* stack =
+ graph.NewNode(common.StateValues(0, SparseInputMask::Dense()));
Node* state_node = graph.NewNode(
common.FrameState(BailoutId::None(), OutputFrameStateCombine::Ignore(),
diff --git a/deps/v8/test/cctest/compiler/test-loop-assignment-analysis.cc b/deps/v8/test/cctest/compiler/test-loop-assignment-analysis.cc
index 7ae14b54c8..b70df3563c 100644
--- a/deps/v8/test/cctest/compiler/test-loop-assignment-analysis.cc
+++ b/deps/v8/test/cctest/compiler/test-loop-assignment-analysis.cc
@@ -5,8 +5,9 @@
#include "src/ast/scopes.h"
#include "src/compilation-info.h"
#include "src/compiler/ast-loop-assignment-analyzer.h"
+#include "src/objects-inl.h"
#include "src/parsing/parse-info.h"
-#include "src/parsing/parser.h"
+#include "src/parsing/parsing.h"
#include "src/parsing/rewriter.h"
#include "test/cctest/cctest.h"
@@ -35,7 +36,7 @@ struct TestHelper : public HandleAndZoneScope {
ParseInfo parse_info(main_zone(), handle(function->shared()));
CompilationInfo info(&parse_info, function);
- CHECK(Parser::ParseStatic(&parse_info));
+ CHECK(parsing::ParseFunction(&parse_info));
CHECK(Rewriter::Rewrite(&parse_info));
DeclarationScope::Analyze(&parse_info, AnalyzeMode::kRegular);
@@ -71,27 +72,8 @@ TEST(SimpleLoop1) {
f.CheckLoopAssignedCount(0, "x");
}
-
-TEST(SimpleLoop2) {
- const char* loops[] = {
- "while (x) { var x = 0; }", "for(;;) { var x = 0; }",
- "for(;x;) { var x = 0; }", "for(;x;x) { var x = 0; }",
- "for(var i = x; x; x) { var x = 0; }", "for(y in 0) { var x = 0; }",
- "for(y of 0) { var x = 0; }", "for(var x = 0; x; x++) { }",
- "for(var x = 0; x++;) { }", "var x; for(;x;x++) { }",
- "var x; do { x = 1; } while (0);", "do { var x = 1; } while (0);"};
-
- for (size_t i = 0; i < arraysize(loops); i++) {
- TestHelper f(loops[i]);
- f.CheckLoopAssignedCount(1, "x");
- }
-}
-
-
-TEST(ForInOf1) {
- const char* loops[] = {
- "for(x in 0) { }", "for(x of 0) { }",
- };
+TEST(ForIn1) {
+ const char* loops[] = {"for(x in 0) { }"};
for (size_t i = 0; i < arraysize(loops); i++) {
TestHelper f(loops[i]);
diff --git a/deps/v8/test/cctest/compiler/test-machine-operator-reducer.cc b/deps/v8/test/cctest/compiler/test-machine-operator-reducer.cc
index cf3da887ba..15bd72c4d4 100644
--- a/deps/v8/test/cctest/compiler/test-machine-operator-reducer.cc
+++ b/deps/v8/test/cctest/compiler/test-machine-operator-reducer.cc
@@ -850,12 +850,12 @@ TEST(ReduceFloat32Sub) {
}
Node* x = R.Parameter();
- Node* zero = R.Constant<float>(0.0);
Node* nan = R.Constant<float>(std::numeric_limits<float>::quiet_NaN());
- R.CheckBinop(x, x, zero); // x - 0 => x
- R.CheckBinop(nan, nan, x); // nan - x => nan
- R.CheckBinop(nan, x, nan); // x - nan => nan
+ // nan - x => nan
+ R.CheckFoldBinop(std::numeric_limits<float>::quiet_NaN(), nan, x);
+ // x - nan => nan
+ R.CheckFoldBinop(std::numeric_limits<float>::quiet_NaN(), x, nan);
}
TEST(ReduceFloat64Sub) {
@@ -870,12 +870,12 @@ TEST(ReduceFloat64Sub) {
}
Node* x = R.Parameter();
- Node* zero = R.Constant<double>(0.0);
Node* nan = R.Constant<double>(std::numeric_limits<double>::quiet_NaN());
- R.CheckBinop(x, x, zero); // x - 0 => x
- R.CheckBinop(nan, nan, x); // nan - x => nan
- R.CheckBinop(nan, x, nan); // x - nan => nan
+ // nan - x => nan
+ R.CheckFoldBinop(std::numeric_limits<double>::quiet_NaN(), nan, x);
+ // x - nan => nan
+ R.CheckFoldBinop(std::numeric_limits<double>::quiet_NaN(), x, nan);
}
// TODO(titzer): test MachineOperatorReducer for Word64And
diff --git a/deps/v8/test/cctest/compiler/test-representation-change.cc b/deps/v8/test/cctest/compiler/test-representation-change.cc
index ab2a1f6dfe..c8519faeb5 100644
--- a/deps/v8/test/cctest/compiler/test-representation-change.cc
+++ b/deps/v8/test/cctest/compiler/test-representation-change.cc
@@ -427,7 +427,7 @@ TEST(SignednessInWord32) {
MachineRepresentation::kFloat64, Type::Number(),
MachineRepresentation::kWord32);
CheckChange(IrOpcode::kCheckedTruncateTaggedToWord32,
- MachineRepresentation::kTagged, Type::NumberOrOddball(),
+ MachineRepresentation::kTagged, Type::NonInternal(),
MachineRepresentation::kWord32,
UseInfo::CheckedNumberOrOddballAsWord32());
diff --git a/deps/v8/test/cctest/compiler/test-run-bytecode-graph-builder.cc b/deps/v8/test/cctest/compiler/test-run-bytecode-graph-builder.cc
index 74a51b915a..ea7fcd6449 100644
--- a/deps/v8/test/cctest/compiler/test-run-bytecode-graph-builder.cc
+++ b/deps/v8/test/cctest/compiler/test-run-bytecode-graph-builder.cc
@@ -10,6 +10,7 @@
#include "src/handles.h"
#include "src/interpreter/bytecode-array-builder.h"
#include "src/interpreter/interpreter.h"
+#include "src/objects-inl.h"
#include "src/parsing/parse-info.h"
#include "test/cctest/cctest.h"
@@ -80,8 +81,6 @@ class BytecodeGraphTester {
i::FLAG_always_opt = false;
i::FLAG_allow_natives_syntax = true;
i::FLAG_loop_assignment_analysis = false;
- // Ensure handler table is generated.
- isolate->interpreter()->Initialize();
}
virtual ~BytecodeGraphTester() {}
@@ -3029,35 +3028,32 @@ TEST(BytecodeGraphBuilderIllegalConstDeclaration) {
}
}
+static int debug_break_count = 0;
+static void DebugEventCounter(const v8::Debug::EventDetails& event_details) {
+ if (event_details.GetEvent() == v8::Break) debug_break_count++;
+}
+
TEST(BytecodeGraphBuilderDebuggerStatement) {
- FLAG_expose_debug_as = "debug";
HandleAndZoneScope scope;
Isolate* isolate = scope.main_isolate();
Zone* zone = scope.main_zone();
+ v8::Debug::SetDebugEventListener(CcTest::isolate(), DebugEventCounter);
+
ExpectedSnippet<0> snippet = {
- "var Debug = debug.Debug;"
- "var count = 0;"
"function f() {"
" debugger;"
"}"
- "function listener(event) {"
- " if (event == Debug.DebugEvent.Break) count++;"
- "}"
- "Debug.setListener(listener);"
- "f();"
- "Debug.setListener(null);"
- "return count;",
- {handle(Smi::FromInt(1), isolate)}};
-
- ScopedVector<char> script(1024);
- SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
- snippet.code_snippet, kFunctionName);
+ "f();",
+ {isolate->factory()->undefined_value()}};
- BytecodeGraphTester tester(isolate, zone, script.start());
+ BytecodeGraphTester tester(isolate, zone, snippet.code_snippet);
auto callable = tester.GetCallable<>();
Handle<Object> return_value = callable().ToHandleChecked();
- CHECK(return_value->SameValue(*snippet.return_value()));
+
+ v8::Debug::SetDebugEventListener(CcTest::isolate(), nullptr);
+ CHECK(return_value.is_identical_to(snippet.return_value()));
+ CHECK_EQ(2, debug_break_count);
}
} // namespace compiler
diff --git a/deps/v8/test/cctest/compiler/test-run-inlining.cc b/deps/v8/test/cctest/compiler/test-run-inlining.cc
deleted file mode 100644
index 22e791a5f8..0000000000
--- a/deps/v8/test/cctest/compiler/test-run-inlining.cc
+++ /dev/null
@@ -1,471 +0,0 @@
-// Copyright 2014 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/compilation-info.h"
-#include "src/frames-inl.h"
-#include "test/cctest/compiler/function-tester.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-namespace {
-
-// Helper to determine inline count via JavaScriptFrame::GetFunctions.
-// Note that a count of 1 indicates that no inlining has occured.
-void AssertInlineCount(const v8::FunctionCallbackInfo<v8::Value>& args) {
- JavaScriptFrameIterator it(CcTest::i_isolate());
- int frames_seen = 0;
- JavaScriptFrame* topmost = it.frame();
- while (!it.done()) {
- JavaScriptFrame* frame = it.frame();
- List<JSFunction*> functions(2);
- frame->GetFunctions(&functions);
- PrintF("%d %s, inline count: %d\n", frames_seen,
- frame->function()->shared()->DebugName()->ToCString().get(),
- functions.length());
- frames_seen++;
- it.Advance();
- }
- List<JSFunction*> functions(2);
- topmost->GetFunctions(&functions);
- CHECK_EQ(args[0]
- ->ToInt32(args.GetIsolate()->GetCurrentContext())
- .ToLocalChecked()
- ->Value(),
- functions.length());
-}
-
-
-void InstallAssertInlineCountHelper(v8::Isolate* isolate) {
- v8::Local<v8::Context> context = isolate->GetCurrentContext();
- v8::Local<v8::FunctionTemplate> t =
- v8::FunctionTemplate::New(isolate, AssertInlineCount);
- CHECK(context->Global()
- ->Set(context, v8_str("AssertInlineCount"),
- t->GetFunction(context).ToLocalChecked())
- .FromJust());
-}
-
-const uint32_t kRestrictedInliningFlags = 0;
-
-const uint32_t kInlineFlags = CompilationInfo::kInliningEnabled;
-
-} // namespace
-
-
-TEST(SimpleInlining) {
- FunctionTester T(
- "function foo(s) { AssertInlineCount(2); return s; };"
- "function bar(s, t) { return foo(s); };"
- "bar;",
- kInlineFlags);
-
- InstallAssertInlineCountHelper(CcTest::isolate());
- T.CheckCall(T.Val(1), T.Val(1), T.Val(2));
-}
-
-
-TEST(SimpleInliningDeopt) {
- FunctionTester T(
- "function foo(s) { %DeoptimizeFunction(bar); return s; };"
- "function bar(s, t) { return foo(s); };"
- "bar;",
- kInlineFlags);
-
- InstallAssertInlineCountHelper(CcTest::isolate());
- T.CheckCall(T.Val(1), T.Val(1), T.Val(2));
-}
-
-
-TEST(SimpleInliningDeoptSelf) {
- FunctionTester T(
- "function foo(s) { %_DeoptimizeNow(); return s; };"
- "function bar(s, t) { return foo(s); };"
- "bar;",
- kInlineFlags);
-
- InstallAssertInlineCountHelper(CcTest::isolate());
- T.CheckCall(T.Val(1), T.Val(1), T.Val(2));
-}
-
-
-TEST(SimpleInliningContext) {
- FunctionTester T(
- "function foo(s) { AssertInlineCount(2); var x = 12; return s + x; };"
- "function bar(s, t) { return foo(s); };"
- "bar;",
- kInlineFlags);
-
- InstallAssertInlineCountHelper(CcTest::isolate());
- T.CheckCall(T.Val(13), T.Val(1), T.Val(2));
-}
-
-
-TEST(SimpleInliningContextDeopt) {
- FunctionTester T(
- "function foo(s) {"
- " AssertInlineCount(2); %DeoptimizeFunction(bar); var x = 12;"
- " return s + x;"
- "};"
- "function bar(s, t) { return foo(s); };"
- "bar;",
- kInlineFlags);
-
- InstallAssertInlineCountHelper(CcTest::isolate());
- T.CheckCall(T.Val(13), T.Val(1), T.Val(2));
-}
-
-
-TEST(CaptureContext) {
- FunctionTester T(
- "var f = (function () {"
- " var x = 42;"
- " function bar(s) { return x + s; };"
- " return (function (s) { return bar(s); });"
- "})();"
- "(function (s) { return f(s) })",
- kInlineFlags);
-
- InstallAssertInlineCountHelper(CcTest::isolate());
- T.CheckCall(T.Val(42 + 12), T.Val(12), T.undefined());
-}
-
-
-// TODO(sigurds) For now we do not inline any native functions. If we do at
-// some point, change this test.
-TEST(DontInlineEval) {
- FunctionTester T(
- "var x = 42;"
- "function bar(s, t) { return eval(\"AssertInlineCount(1); x\") };"
- "bar;",
- kInlineFlags);
-
- InstallAssertInlineCountHelper(CcTest::isolate());
- T.CheckCall(T.Val(42), T.Val("x"), T.undefined());
-}
-
-
-TEST(InlineOmitArguments) {
- FunctionTester T(
- "var x = 42;"
- "function bar(s, t, u, v) { AssertInlineCount(2); return x + s; };"
- "function foo(s, t) { return bar(s); };"
- "foo;",
- kInlineFlags);
-
- InstallAssertInlineCountHelper(CcTest::isolate());
- T.CheckCall(T.Val(42 + 12), T.Val(12), T.undefined());
-}
-
-
-TEST(InlineOmitArgumentsObject) {
- FunctionTester T(
- "function bar(s, t, u, v) { AssertInlineCount(2); return arguments; };"
- "function foo(s, t) { var args = bar(s);"
- " return args.length == 1 &&"
- " args[0] == 11; };"
- "foo;",
- kInlineFlags);
-
- InstallAssertInlineCountHelper(CcTest::isolate());
- T.CheckCall(T.true_value(), T.Val(11), T.undefined());
-}
-
-
-TEST(InlineOmitArgumentsDeopt) {
- FunctionTester T(
- "function foo(s,t,u,v) { AssertInlineCount(2);"
- " %DeoptimizeFunction(bar); return baz(); };"
- "function bar() { return foo(11); };"
- "function baz() { return foo.arguments.length == 1 &&"
- " foo.arguments[0] == 11; }"
- "bar;",
- kInlineFlags);
-
- InstallAssertInlineCountHelper(CcTest::isolate());
- T.CheckCall(T.true_value(), T.Val(12), T.Val(14));
-}
-
-
-TEST(InlineSurplusArguments) {
- FunctionTester T(
- "var x = 42;"
- "function foo(s) { AssertInlineCount(2); return x + s; };"
- "function bar(s, t) { return foo(s, t, 13); };"
- "bar;",
- kInlineFlags);
-
- InstallAssertInlineCountHelper(CcTest::isolate());
- T.CheckCall(T.Val(42 + 12), T.Val(12), T.undefined());
-}
-
-
-TEST(InlineSurplusArgumentsObject) {
- FunctionTester T(
- "function foo(s) { AssertInlineCount(2); return arguments; };"
- "function bar(s, t) { var args = foo(s, t, 13);"
- " return args.length == 3 &&"
- " args[0] == 11 &&"
- " args[1] == 12 &&"
- " args[2] == 13; };"
- "bar;",
- kInlineFlags);
-
- InstallAssertInlineCountHelper(CcTest::isolate());
- T.CheckCall(T.true_value(), T.Val(11), T.Val(12));
-}
-
-
-TEST(InlineSurplusArgumentsDeopt) {
- FunctionTester T(
- "function foo(s) { AssertInlineCount(2); %DeoptimizeFunction(bar);"
- " return baz(); };"
- "function bar() { return foo(13, 14, 15); };"
- "function baz() { return foo.arguments.length == 3 &&"
- " foo.arguments[0] == 13 &&"
- " foo.arguments[1] == 14 &&"
- " foo.arguments[2] == 15; }"
- "bar;",
- kInlineFlags);
-
- InstallAssertInlineCountHelper(CcTest::isolate());
- T.CheckCall(T.true_value(), T.Val(12), T.Val(14));
-}
-
-
-TEST(InlineTwice) {
- FunctionTester T(
- "var x = 42;"
- "function bar(s) { AssertInlineCount(2); return x + s; };"
- "function foo(s, t) { return bar(s) + bar(t); };"
- "foo;",
- kInlineFlags);
-
- InstallAssertInlineCountHelper(CcTest::isolate());
- T.CheckCall(T.Val(2 * 42 + 12 + 4), T.Val(12), T.Val(4));
-}
-
-
-TEST(InlineTwiceDependent) {
- FunctionTester T(
- "var x = 42;"
- "function foo(s) { AssertInlineCount(2); return x + s; };"
- "function bar(s,t) { return foo(foo(s)); };"
- "bar;",
- kInlineFlags);
-
- InstallAssertInlineCountHelper(CcTest::isolate());
- T.CheckCall(T.Val(42 + 42 + 12), T.Val(12), T.Val(4));
-}
-
-
-TEST(InlineTwiceDependentDiamond) {
- FunctionTester T(
- "var x = 41;"
- "function foo(s) { AssertInlineCount(2); if (s % 2 == 0) {"
- " return x - s } else { return x + s; } };"
- "function bar(s,t) { return foo(foo(s)); };"
- "bar;",
- kInlineFlags);
-
- InstallAssertInlineCountHelper(CcTest::isolate());
- T.CheckCall(T.Val(-11), T.Val(11), T.Val(4));
-}
-
-
-TEST(InlineTwiceDependentDiamondDifferent) {
- FunctionTester T(
- "var x = 41;"
- "function foo(s,t) { AssertInlineCount(2); if (s % 2 == 0) {"
- " return x - s * t } else { return x + s * t; } };"
- "function bar(s,t) { return foo(foo(s, 3), 5); };"
- "bar;",
- kInlineFlags);
-
- InstallAssertInlineCountHelper(CcTest::isolate());
- T.CheckCall(T.Val(-329), T.Val(11), T.Val(4));
-}
-
-
-TEST(InlineLoopGuardedEmpty) {
- FunctionTester T(
- "function foo(s) { AssertInlineCount(2); if (s) while (s); return s; };"
- "function bar(s,t) { return foo(s); };"
- "bar;",
- kInlineFlags);
-
- InstallAssertInlineCountHelper(CcTest::isolate());
- T.CheckCall(T.Val(0.0), T.Val(0.0), T.Val(4));
-}
-
-
-TEST(InlineLoopGuardedOnce) {
- FunctionTester T(
- "function foo(s,t) { AssertInlineCount(2); if (t > 0) while (s > 0) {"
- " s = s - 1; }; return s; };"
- "function bar(s,t) { return foo(s,t); };"
- "bar;",
- kInlineFlags);
-
- InstallAssertInlineCountHelper(CcTest::isolate());
- T.CheckCall(T.Val(0.0), T.Val(11), T.Val(4));
-}
-
-
-TEST(InlineLoopGuardedTwice) {
- FunctionTester T(
- "function foo(s,t) { AssertInlineCount(2); if (t > 0) while (s > 0) {"
- " s = s - 1; }; return s; };"
- "function bar(s,t) { return foo(foo(s,t),t); };"
- "bar;",
- kInlineFlags);
-
- InstallAssertInlineCountHelper(CcTest::isolate());
- T.CheckCall(T.Val(0.0), T.Val(11), T.Val(4));
-}
-
-
-TEST(InlineLoopUnguardedEmpty) {
- FunctionTester T(
- "function foo(s) { AssertInlineCount(2); while (s); return s; };"
- "function bar(s, t) { return foo(s); };"
- "bar;",
- kInlineFlags);
-
- InstallAssertInlineCountHelper(CcTest::isolate());
- T.CheckCall(T.Val(0.0), T.Val(0.0), T.Val(4));
-}
-
-
-TEST(InlineLoopUnguardedOnce) {
- FunctionTester T(
- "function foo(s) { AssertInlineCount(2); while (s) {"
- " s = s - 1; }; return s; };"
- "function bar(s, t) { return foo(s); };"
- "bar;",
- kInlineFlags);
-
- InstallAssertInlineCountHelper(CcTest::isolate());
- T.CheckCall(T.Val(0.0), T.Val(0.0), T.Val(4));
-}
-
-
-TEST(InlineLoopUnguardedTwice) {
- FunctionTester T(
- "function foo(s) { AssertInlineCount(2); while (s > 0) {"
- " s = s - 1; }; return s; };"
- "function bar(s,t) { return foo(foo(s,t),t); };"
- "bar;",
- kInlineFlags);
-
- InstallAssertInlineCountHelper(CcTest::isolate());
- T.CheckCall(T.Val(0.0), T.Val(0.0), T.Val(4));
-}
-
-
-TEST(InlineStrictIntoNonStrict) {
- FunctionTester T(
- "var x = Object.create({}, { y: { value:42, writable:false } });"
- "function foo(s) { 'use strict';"
- " x.y = 9; };"
- "function bar(s,t) { return foo(s); };"
- "bar;",
- kInlineFlags);
-
- InstallAssertInlineCountHelper(CcTest::isolate());
- T.CheckThrows(T.undefined(), T.undefined());
-}
-
-
-TEST(InlineNonStrictIntoStrict) {
- FunctionTester T(
- "var x = Object.create({}, { y: { value:42, writable:false } });"
- "function foo(s) { x.y = 9; return x.y; };"
- "function bar(s,t) { \'use strict\'; return foo(s); };"
- "bar;",
- kInlineFlags);
-
- InstallAssertInlineCountHelper(CcTest::isolate());
- T.CheckCall(T.Val(42), T.undefined(), T.undefined());
-}
-
-
-TEST(InlineWithArguments) {
- FunctionTester T(
- "function foo(s,t,u) { AssertInlineCount(2);"
- " return foo.arguments.length == 3 &&"
- " foo.arguments[0] == 13 &&"
- " foo.arguments[1] == 14 &&"
- " foo.arguments[2] == 15;"
- "}"
- "function bar() { return foo(13, 14, 15); };"
- "bar;",
- kInlineFlags);
-
- InstallAssertInlineCountHelper(CcTest::isolate());
- T.CheckCall(T.true_value(), T.Val(12), T.Val(14));
-}
-
-
-TEST(InlineBuiltin) {
- FunctionTester T(
- "function foo(s,t,u) { AssertInlineCount(2); return true; }"
- "function bar() { return foo(); };"
- "%SetForceInlineFlag(foo);"
- "bar;",
- kRestrictedInliningFlags);
-
- InstallAssertInlineCountHelper(CcTest::isolate());
- T.CheckCall(T.true_value());
-}
-
-
-TEST(InlineNestedBuiltin) {
- FunctionTester T(
- "function foo(s,t,u) { AssertInlineCount(3); return true; }"
- "function baz(s,t,u) { return foo(s,t,u); }"
- "function bar() { return baz(); };"
- "%SetForceInlineFlag(foo);"
- "%SetForceInlineFlag(baz);"
- "bar;",
- kRestrictedInliningFlags);
-
- InstallAssertInlineCountHelper(CcTest::isolate());
- T.CheckCall(T.true_value());
-}
-
-
-TEST(InlineSelfRecursive) {
- FunctionTester T(
- "function foo(x) { "
- " AssertInlineCount(1);"
- " if (x == 1) return foo(12);"
- " return x;"
- "}"
- "foo;",
- kInlineFlags);
-
- InstallAssertInlineCountHelper(CcTest::isolate());
- T.CheckCall(T.Val(12), T.Val(1));
-}
-
-
-TEST(InlineMutuallyRecursive) {
- FunctionTester T(
- "function bar(x) { AssertInlineCount(2); return foo(x); }"
- "function foo(x) { "
- " if (x == 1) return bar(42);"
- " return x;"
- "}"
- "foo;",
- kInlineFlags);
-
- InstallAssertInlineCountHelper(CcTest::isolate());
- T.CheckCall(T.Val(42), T.Val(1));
-}
-
-} // namespace compiler
-} // namespace internal
-} // namespace v8
diff --git a/deps/v8/test/cctest/compiler/test-run-intrinsics.cc b/deps/v8/test/cctest/compiler/test-run-intrinsics.cc
index 47116ad674..515e096f44 100644
--- a/deps/v8/test/cctest/compiler/test-run-intrinsics.cc
+++ b/deps/v8/test/cctest/compiler/test-run-intrinsics.cc
@@ -80,21 +80,6 @@ TEST(IsFunction) {
}
-TEST(IsRegExp) {
- FunctionTester T("(function(a) { return %_IsRegExp(a); })", flags);
-
- T.CheckFalse(T.NewObject("new Date()"));
- T.CheckFalse(T.NewObject("(function() {})"));
- T.CheckFalse(T.NewObject("([1])"));
- T.CheckFalse(T.NewObject("({})"));
- T.CheckTrue(T.NewObject("(/x/)"));
- T.CheckFalse(T.undefined());
- T.CheckFalse(T.null());
- T.CheckFalse(T.Val("x"));
- T.CheckFalse(T.Val(1));
-}
-
-
TEST(IsSmi) {
FunctionTester T("(function(a) { return %_IsSmi(a); })", flags);
diff --git a/deps/v8/test/cctest/compiler/test-run-jscalls.cc b/deps/v8/test/cctest/compiler/test-run-jscalls.cc
index 64bd67cc0a..371d0f94fa 100644
--- a/deps/v8/test/cctest/compiler/test-run-jscalls.cc
+++ b/deps/v8/test/cctest/compiler/test-run-jscalls.cc
@@ -5,6 +5,7 @@
#include "src/api.h"
#include "src/contexts.h"
#include "src/flags.h"
+#include "src/objects-inl.h"
#include "src/objects.h"
#include "test/cctest/compiler/function-tester.h"
diff --git a/deps/v8/test/cctest/compiler/test-run-machops.cc b/deps/v8/test/cctest/compiler/test-run-machops.cc
index 2794aec51e..195f0a91dc 100644
--- a/deps/v8/test/cctest/compiler/test-run-machops.cc
+++ b/deps/v8/test/cctest/compiler/test-run-machops.cc
@@ -3797,6 +3797,30 @@ TEST(RunFloat32Min) {
}
}
+TEST(RunFloat64Max) {
+ RawMachineAssemblerTester<int32_t> m;
+ Float64BinopTester bt(&m);
+ bt.AddReturn(m.Float64Max(bt.param0, bt.param1));
+
+ FOR_FLOAT64_INPUTS(pl) {
+ FOR_FLOAT64_INPUTS(pr) {
+ CHECK_DOUBLE_EQ(JSMax(*pl, *pr), bt.call(*pl, *pr));
+ }
+ }
+}
+
+TEST(RunFloat64Min) {
+ RawMachineAssemblerTester<int32_t> m;
+ Float64BinopTester bt(&m);
+ bt.AddReturn(m.Float64Min(bt.param0, bt.param1));
+
+ FOR_FLOAT64_INPUTS(pl) {
+ FOR_FLOAT64_INPUTS(pr) {
+ CHECK_DOUBLE_EQ(JSMin(*pl, *pr), bt.call(*pl, *pr));
+ }
+ }
+}
+
TEST(RunFloat32SubP) {
RawMachineAssemblerTester<int32_t> m;
Float32BinopTester bt(&m);
diff --git a/deps/v8/test/cctest/compiler/test-run-native-calls.cc b/deps/v8/test/cctest/compiler/test-run-native-calls.cc
index 89629ec090..e877d258b5 100644
--- a/deps/v8/test/cctest/compiler/test-run-native-calls.cc
+++ b/deps/v8/test/cctest/compiler/test-run-native-calls.cc
@@ -458,12 +458,14 @@ class Computer {
CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, &csig);
RawMachineAssembler raw(isolate, &graph, cdesc);
Node* target = raw.HeapConstant(inner);
- Node** args = zone.NewArray<Node*>(num_params);
+ Node** inputs = zone.NewArray<Node*>(num_params + 1);
+ int input_count = 0;
+ inputs[input_count++] = target;
for (int i = 0; i < num_params; i++) {
- args[i] = io.MakeConstant(raw, io.input[i]);
+ inputs[input_count++] = io.MakeConstant(raw, io.input[i]);
}
- Node* call = raw.CallN(desc, target, args);
+ Node* call = raw.CallN(desc, input_count, inputs);
Node* store = io.StoreOutput(raw, call);
USE(store);
raw.Return(raw.Int32Constant(seed));
@@ -491,12 +493,14 @@ class Computer {
RawMachineAssembler raw(isolate, &graph, cdesc);
Node* base = raw.PointerConstant(io.input);
Node* target = raw.HeapConstant(inner);
- Node** args = zone.NewArray<Node*>(kMaxParamCount);
+ Node** inputs = zone.NewArray<Node*>(kMaxParamCount + 1);
+ int input_count = 0;
+ inputs[input_count++] = target;
for (int i = 0; i < num_params; i++) {
- args[i] = io.LoadInput(raw, base, i);
+ inputs[input_count++] = io.LoadInput(raw, base, i);
}
- Node* call = raw.CallN(desc, target, args);
+ Node* call = raw.CallN(desc, input_count, inputs);
Node* store = io.StoreOutput(raw, call);
USE(store);
raw.Return(raw.Int32Constant(seed));
@@ -588,13 +592,15 @@ static void CopyTwentyInt32(CallDescriptor* desc) {
RawMachineAssembler raw(isolate, &graph, cdesc);
Node* base = raw.PointerConstant(input);
Node* target = raw.HeapConstant(inner);
- Node** args = zone.NewArray<Node*>(kNumParams);
+ Node** inputs = zone.NewArray<Node*>(kNumParams + 1);
+ int input_count = 0;
+ inputs[input_count++] = target;
for (int i = 0; i < kNumParams; i++) {
Node* offset = raw.Int32Constant(i * sizeof(int32_t));
- args[i] = raw.Load(MachineType::Int32(), base, offset);
+ inputs[input_count++] = raw.Load(MachineType::Int32(), base, offset);
}
- Node* call = raw.CallN(desc, target, args);
+ Node* call = raw.CallN(desc, input_count, inputs);
raw.Return(call);
wrapper =
CompileGraph("CopyTwentyInt32-wrapper", cdesc, &graph, raw.Export());
@@ -970,12 +976,14 @@ static void Build_Select_With_Call(CallDescriptor* desc,
{
// Build a call to the function that does the select.
Node* target = raw.HeapConstant(inner);
- Node** args = raw.zone()->NewArray<Node*>(num_params);
+ Node** inputs = raw.zone()->NewArray<Node*>(num_params + 1);
+ int input_count = 0;
+ inputs[input_count++] = target;
for (int i = 0; i < num_params; i++) {
- args[i] = raw.Parameter(i);
+ inputs[input_count++] = raw.Parameter(i);
}
- Node* call = raw.CallN(desc, target, args);
+ Node* call = raw.CallN(desc, input_count, inputs);
raw.Return(call);
}
}
@@ -1075,7 +1083,9 @@ void MixedParamTest(int start) {
CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, &csig);
RawMachineAssembler raw(isolate, &graph, cdesc);
Node* target = raw.HeapConstant(select);
- Node** args = zone.NewArray<Node*>(num_params);
+ Node** inputs = zone.NewArray<Node*>(num_params + 1);
+ int input_count = 0;
+ inputs[input_count++] = target;
int64_t constant = 0x0102030405060708;
for (int i = 0; i < num_params; i++) {
MachineType param_type = sig->GetParam(i);
@@ -1102,11 +1112,11 @@ void MixedParamTest(int start) {
}
CHECK_NOT_NULL(konst);
- args[i] = konst;
+ inputs[input_count++] = konst;
constant += 0x1010101010101010;
}
- Node* call = raw.CallN(desc, target, args);
+ Node* call = raw.CallN(desc, input_count, inputs);
Node* store =
raw.StoreToPointer(output, sig->GetReturn().representation(), call);
USE(store);
@@ -1178,14 +1188,16 @@ void TestStackSlot(MachineType slot_type, T expected) {
BufferedRawMachineAssemblerTester<T> f(slot_type);
Node* target = f.HeapConstant(inner);
Node* stack_slot = f.StackSlot(slot_type.representation());
- Node* args[12];
+ Node* nodes[14];
+ int input_count = 0;
+ nodes[input_count++] = target;
for (int i = 0; i < 10; i++) {
- args[i] = f.Int32Constant(i);
+ nodes[input_count++] = f.Int32Constant(i);
}
- args[10] = f.Parameter(0);
- args[11] = stack_slot;
+ nodes[input_count++] = f.Parameter(0);
+ nodes[input_count++] = stack_slot;
- f.CallN(desc, target, args);
+ f.CallN(desc, input_count, nodes);
f.Return(f.Load(slot_type, stack_slot, f.IntPtrConstant(0)));
CHECK_EQ(expected, f.Call(expected));
diff --git a/deps/v8/test/cctest/compiler/test-run-variables.cc b/deps/v8/test/cctest/compiler/test-run-variables.cc
index 9d6291a5aa..d1f564a51c 100644
--- a/deps/v8/test/cctest/compiler/test-run-variables.cc
+++ b/deps/v8/test/cctest/compiler/test-run-variables.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "src/api.h"
+#include "src/objects-inl.h"
#include "test/cctest/compiler/function-tester.h"
namespace v8 {
diff --git a/deps/v8/test/cctest/compiler/test-run-wasm-machops.cc b/deps/v8/test/cctest/compiler/test-run-wasm-machops.cc
index c3f42388d4..9359b25779 100644
--- a/deps/v8/test/cctest/compiler/test-run-wasm-machops.cc
+++ b/deps/v8/test/cctest/compiler/test-run-wasm-machops.cc
@@ -40,6 +40,26 @@ static void UpdateMemoryReferences(Handle<Code> code, Address old_base,
}
}
+static void UpdateFunctionTableSizeReferences(Handle<Code> code,
+ uint32_t old_size,
+ uint32_t new_size) {
+ Isolate* isolate = CcTest::i_isolate();
+ bool modified = false;
+ int mode_mask =
+ RelocInfo::ModeMask(RelocInfo::WASM_FUNCTION_TABLE_SIZE_REFERENCE);
+ for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
+ RelocInfo::Mode mode = it.rinfo()->rmode();
+ if (RelocInfo::IsWasmFunctionTableSizeReference(mode)) {
+ it.rinfo()->update_wasm_function_table_size_reference(old_size, new_size);
+ modified = true;
+ }
+ }
+ if (modified) {
+ Assembler::FlushICache(isolate, code->instruction_start(),
+ code->instruction_size());
+ }
+}
+
template <typename CType>
static void RunLoadStoreRelocation(MachineType rep) {
const int kNumElems = 2;
@@ -146,7 +166,7 @@ TEST(RunLoadStoreRelocationOffset) {
RunLoadStoreRelocationOffset<double>(MachineType::Float64());
}
-TEST(Uint32LessThanRelocation) {
+TEST(Uint32LessThanMemoryRelocation) {
RawMachineAssemblerTester<uint32_t> m;
RawMachineLabel within_bounds, out_of_bounds;
Node* index = m.Int32Constant(0x200);
@@ -168,3 +188,25 @@ TEST(Uint32LessThanRelocation) {
// Check that after limit is increased, index is within bounds.
CHECK_EQ(0xacedu, m.Call());
}
+
+TEST(Uint32LessThanFunctionTableRelocation) {
+ RawMachineAssemblerTester<uint32_t> m;
+ RawMachineLabel within_bounds, out_of_bounds;
+ Node* index = m.Int32Constant(0x200);
+ Node* limit = m.RelocatableInt32Constant(
+ 0x200, RelocInfo::WASM_FUNCTION_TABLE_SIZE_REFERENCE);
+ Node* cond = m.AddNode(m.machine()->Uint32LessThan(), index, limit);
+ m.Branch(cond, &within_bounds, &out_of_bounds);
+ m.Bind(&within_bounds);
+ m.Return(m.Int32Constant(0xaced));
+ m.Bind(&out_of_bounds);
+ m.Return(m.Int32Constant(0xdeadbeef));
+ // Check that index is out of bounds with current size
+ CHECK_EQ(0xdeadbeef, m.Call());
+ m.GenerateCode();
+
+ Handle<Code> code = m.GetCode();
+ UpdateFunctionTableSizeReferences(code, 0x200, 0x400);
+ // Check that after limit is increased, index is within bounds.
+ CHECK_EQ(0xaced, m.Call());
+}
diff --git a/deps/v8/test/cctest/heap/heap-tester.h b/deps/v8/test/cctest/heap/heap-tester.h
index 99d39ca7ab..acfbe92bb6 100644
--- a/deps/v8/test/cctest/heap/heap-tester.h
+++ b/deps/v8/test/cctest/heap/heap-tester.h
@@ -34,6 +34,7 @@
V(Regress589413) \
V(Regress658718) \
V(Regress670675) \
+ V(Regress5831) \
V(WriteBarriersInCopyJSObject)
#define HEAP_TEST(Name) \
diff --git a/deps/v8/test/cctest/heap/heap-utils.cc b/deps/v8/test/cctest/heap/heap-utils.cc
index c44f82f1d9..35a584b739 100644
--- a/deps/v8/test/cctest/heap/heap-utils.cc
+++ b/deps/v8/test/cctest/heap/heap-utils.cc
@@ -142,6 +142,7 @@ void SimulateFullSpace(v8::internal::NewSpace* space,
}
void SimulateIncrementalMarking(i::Heap* heap, bool force_completion) {
+ CHECK(FLAG_incremental_marking);
i::IncrementalMarking* marking = heap->incremental_marking();
i::MarkCompactCollector* collector = heap->mark_compact_collector();
if (collector->sweeping_in_progress()) {
diff --git a/deps/v8/test/cctest/heap/test-alloc.cc b/deps/v8/test/cctest/heap/test-alloc.cc
index d7031e876d..3485c0ab07 100644
--- a/deps/v8/test/cctest/heap/test-alloc.cc
+++ b/deps/v8/test/cctest/heap/test-alloc.cc
@@ -30,6 +30,8 @@
#include "src/accessors.h"
#include "src/api.h"
+#include "src/objects-inl.h"
+#include "src/property.h"
#include "test/cctest/heap/heap-tester.h"
#include "test/cctest/heap/heap-utils.h"
@@ -154,8 +156,8 @@ TEST(StressJS) {
Handle<AccessorInfo> foreign = TestAccessorInfo(isolate, attrs);
Map::EnsureDescriptorSlack(map, 1);
- AccessorConstantDescriptor d(Handle<Name>(Name::cast(foreign->name())),
- foreign, attrs);
+ Descriptor d = Descriptor::AccessorConstant(
+ Handle<Name>(Name::cast(foreign->name())), foreign, attrs);
map->AppendDescriptor(&d);
// Add the Foo constructor the global object.
diff --git a/deps/v8/test/cctest/heap/test-array-buffer-tracker.cc b/deps/v8/test/cctest/heap/test-array-buffer-tracker.cc
index 0f3663041f..11bc4c0727 100644
--- a/deps/v8/test/cctest/heap/test-array-buffer-tracker.cc
+++ b/deps/v8/test/cctest/heap/test-array-buffer-tracker.cc
@@ -4,7 +4,9 @@
#include "src/api.h"
#include "src/heap/array-buffer-tracker.h"
+#include "src/heap/spaces.h"
#include "src/isolate.h"
+#include "src/objects-inl.h"
#include "test/cctest/cctest.h"
#include "test/cctest/heap/heap-utils.h"
@@ -188,6 +190,7 @@ TEST(ArrayBuffer_UnregisterDuringSweep) {
}
TEST(ArrayBuffer_NonLivePromotion) {
+ if (!FLAG_incremental_marking) return;
// The test verifies that the marking state is preserved when promoting
// a buffer to old space.
CcTest::InitializeVM();
@@ -223,6 +226,7 @@ TEST(ArrayBuffer_NonLivePromotion) {
}
TEST(ArrayBuffer_LivePromotion) {
+ if (!FLAG_incremental_marking) return;
// The test verifies that the marking state is preserved when promoting
// a buffer to old space.
CcTest::InitializeVM();
@@ -257,6 +261,7 @@ TEST(ArrayBuffer_LivePromotion) {
}
TEST(ArrayBuffer_SemiSpaceCopyThenPagePromotion) {
+ if (!i::FLAG_incremental_marking) return;
// The test verifies that the marking state is preserved across semispace
// copy.
CcTest::InitializeVM();
diff --git a/deps/v8/test/cctest/heap/test-heap.cc b/deps/v8/test/cctest/heap/test-heap.cc
index 19474c3e95..a6cc7e8251 100644
--- a/deps/v8/test/cctest/heap/test-heap.cc
+++ b/deps/v8/test/cctest/heap/test-heap.cc
@@ -28,6 +28,7 @@
#include <stdlib.h>
#include <utility>
+#include "src/code-stubs.h"
#include "src/compilation-cache.h"
#include "src/context-measure.h"
#include "src/deoptimizer.h"
@@ -1362,6 +1363,7 @@ TEST(TestCodeFlushingPreAged) {
TEST(TestCodeFlushingIncremental) {
+ if (!i::FLAG_incremental_marking) return;
// If we do not flush code this test is invalid.
if (!FLAG_flush_code) return;
i::FLAG_allow_natives_syntax = true;
@@ -1434,6 +1436,7 @@ TEST(TestCodeFlushingIncremental) {
TEST(TestCodeFlushingIncrementalScavenge) {
+ if (!FLAG_incremental_marking) return;
// If we do not flush code this test is invalid.
if (!FLAG_flush_code) return;
i::FLAG_allow_natives_syntax = true;
@@ -1484,8 +1487,8 @@ TEST(TestCodeFlushingIncrementalScavenge) {
// object is still located in new-space.
const int kAgingThreshold = 6;
for (int i = 0; i < kAgingThreshold; i++) {
- function->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2));
- function2->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2));
+ function->shared()->code()->MakeOlder();
+ function2->shared()->code()->MakeOlder();
}
// Simulate incremental marking so that the functions are enqueued as
@@ -1505,6 +1508,7 @@ TEST(TestCodeFlushingIncrementalScavenge) {
TEST(TestCodeFlushingIncrementalAbort) {
+ if (!i::FLAG_incremental_marking) return;
// If we do not flush code this test is invalid.
if (!FLAG_flush_code) return;
i::FLAG_allow_natives_syntax = true;
@@ -1542,7 +1546,7 @@ TEST(TestCodeFlushingIncrementalAbort) {
// Bump the code age so that flushing is triggered.
const int kAgingThreshold = 6;
for (int i = 0; i < kAgingThreshold; i++) {
- function->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2));
+ function->shared()->code()->MakeOlder();
}
// Simulate incremental marking so that the function is enqueued as
@@ -1571,6 +1575,7 @@ TEST(TestCodeFlushingIncrementalAbort) {
}
TEST(TestUseOfIncrementalBarrierOnCompileLazy) {
+ if (!i::FLAG_incremental_marking) return;
// Turn off always_opt because it interferes with running the built-in for
// the last call to g().
i::FLAG_always_opt = false;
@@ -1615,7 +1620,6 @@ TEST(TestUseOfIncrementalBarrierOnCompileLazy) {
TEST(CompilationCacheCachingBehavior) {
// If we do not flush code, or have the compilation cache turned off, this
// test is invalid.
- i::FLAG_allow_natives_syntax = true;
if (!FLAG_flush_code || !FLAG_compilation_cache) {
return;
}
@@ -1643,9 +1647,8 @@ TEST(CompilationCacheCachingBehavior) {
// The script should be in the cache now.
MaybeHandle<SharedFunctionInfo> info = compilation_cache->LookupScript(
- source, Handle<Object>(), 0, 0,
- v8::ScriptOriginOptions(false, true, false), native_context,
- language_mode);
+ source, Handle<Object>(), 0, 0, v8::ScriptOriginOptions(true, false),
+ native_context, language_mode);
CHECK(!info.is_null());
// Check that the code cache entry survives at least on GC.
@@ -1653,29 +1656,26 @@ TEST(CompilationCacheCachingBehavior) {
// immediately.)
if (!FLAG_optimize_for_size) {
CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
- info = compilation_cache->LookupScript(
- source, Handle<Object>(), 0, 0,
- v8::ScriptOriginOptions(false, true, false), native_context,
- language_mode);
+ info = compilation_cache->LookupScript(source, Handle<Object>(), 0, 0,
+ v8::ScriptOriginOptions(true, false),
+ native_context, language_mode);
CHECK(!info.is_null());
}
// Progress code age until it's old and ready for GC.
- while (!info.ToHandleChecked()->code()->IsOld()) {
- // To guarantee progress, we have to MakeOlder with different parities.
- // We can't just use NO_MARKING_PARITY, since e.g. kExecutedOnceCodeAge is
- // always NO_MARKING_PARITY and the code age only progresses if the parity
- // is different.
- info.ToHandleChecked()->code()->MakeOlder(ODD_MARKING_PARITY);
- info.ToHandleChecked()->code()->MakeOlder(EVEN_MARKING_PARITY);
+ const int kAgingThreshold = 6;
+ for (int i = 0; i < kAgingThreshold; i++) {
+ info.ToHandleChecked()->code()->MakeOlder();
+ if (info.ToHandleChecked()->HasBytecodeArray()) {
+ info.ToHandleChecked()->bytecode_array()->MakeOlder();
+ }
}
CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
// Ensure code aging cleared the entry from the cache.
- info = compilation_cache->LookupScript(
- source, Handle<Object>(), 0, 0,
- v8::ScriptOriginOptions(false, true, false), native_context,
- language_mode);
+ info = compilation_cache->LookupScript(source, Handle<Object>(), 0, 0,
+ v8::ScriptOriginOptions(true, false),
+ native_context, language_mode);
CHECK(info.is_null());
}
@@ -1712,7 +1712,7 @@ static int CountOptimizedUserFunctions(v8::Local<v8::Context> context) {
Handle<Context> icontext = v8::Utils::OpenHandle(*context);
Object* object = icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST);
while (object->IsJSFunction() &&
- !JSFunction::cast(object)->shared()->IsBuiltin()) {
+ JSFunction::cast(object)->shared()->IsUserJavaScript()) {
count++;
object = JSFunction::cast(object)->next_function_link();
}
@@ -1854,7 +1854,7 @@ static int CountOptimizedUserFunctionsWithGC(v8::Local<v8::Context> context,
Handle<Object> object(icontext->get(Context::OPTIMIZED_FUNCTIONS_LIST),
isolate);
while (object->IsJSFunction() &&
- !Handle<JSFunction>::cast(object)->shared()->IsBuiltin()) {
+ Handle<JSFunction>::cast(object)->shared()->IsUserJavaScript()) {
count++;
if (count == n)
isolate->heap()->CollectAllGarbage(
@@ -2608,6 +2608,7 @@ TEST(LeakNativeContextViaMapProto) {
TEST(InstanceOfStubWriteBarrier) {
+ if (!i::FLAG_incremental_marking) return;
i::FLAG_allow_natives_syntax = true;
#ifdef VERIFY_HEAP
i::FLAG_verify_heap = true;
@@ -2674,6 +2675,7 @@ int GetProfilerTicks(SharedFunctionInfo* shared) {
} // namespace
TEST(ResetSharedFunctionInfoCountersDuringIncrementalMarking) {
+ if (!i::FLAG_incremental_marking) return;
i::FLAG_stress_compaction = false;
i::FLAG_allow_natives_syntax = true;
#ifdef VERIFY_HEAP
@@ -2765,6 +2767,7 @@ TEST(ResetSharedFunctionInfoCountersDuringMarkSweep) {
HEAP_TEST(GCFlags) {
+ if (!i::FLAG_incremental_marking) return;
CcTest::InitializeVM();
Heap* heap = CcTest::heap();
@@ -2797,6 +2800,7 @@ HEAP_TEST(GCFlags) {
TEST(IdleNotificationFinishMarking) {
+ if (!i::FLAG_incremental_marking) return;
i::FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
const int initial_gc_count = CcTest::heap()->gc_count();
@@ -3296,6 +3300,7 @@ static int CountMapTransitions(Map* map) {
// Test that map transitions are cleared and maps are collected with
// incremental marking as well.
TEST(Regress1465) {
+ if (!i::FLAG_incremental_marking) return;
i::FLAG_stress_compaction = false;
i::FLAG_allow_natives_syntax = true;
i::FLAG_trace_incremental_marking = true;
@@ -3671,6 +3676,7 @@ TEST(PrintSharedFunctionInfo) {
TEST(IncrementalMarkingPreservesMonomorphicCallIC) {
+ if (!FLAG_incremental_marking) return;
if (i::FLAG_always_opt) return;
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
@@ -3746,6 +3752,7 @@ static void CheckVectorIC(Handle<JSFunction> f, int slot_index,
}
TEST(IncrementalMarkingPreservesMonomorphicConstructor) {
+ if (!i::FLAG_incremental_marking) return;
if (i::FLAG_always_opt) return;
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
@@ -3769,6 +3776,7 @@ TEST(IncrementalMarkingPreservesMonomorphicConstructor) {
}
TEST(IncrementalMarkingPreservesMonomorphicIC) {
+ if (!i::FLAG_incremental_marking) return;
if (i::FLAG_always_opt) return;
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
@@ -3790,6 +3798,7 @@ TEST(IncrementalMarkingPreservesMonomorphicIC) {
}
TEST(IncrementalMarkingPreservesPolymorphicIC) {
+ if (!i::FLAG_incremental_marking) return;
if (i::FLAG_always_opt) return;
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
@@ -3827,6 +3836,7 @@ TEST(IncrementalMarkingPreservesPolymorphicIC) {
}
TEST(ContextDisposeDoesntClearPolymorphicIC) {
+ if (!i::FLAG_incremental_marking) return;
if (i::FLAG_always_opt) return;
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
@@ -3982,6 +3992,7 @@ UNINITIALIZED_TEST(ReleaseStackTraceData) {
TEST(Regress159140) {
+ if (!i::FLAG_incremental_marking) return;
i::FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
@@ -4023,7 +4034,7 @@ TEST(Regress159140) {
CHECK(g->is_compiled());
const int kAgingThreshold = 6;
for (int i = 0; i < kAgingThreshold; i++) {
- g->code()->MakeOlder(static_cast<MarkingParity>(i % 2));
+ g->code()->MakeOlder();
}
code = inner_scope.CloseAndEscape(Handle<Code>(f->code()));
@@ -4042,6 +4053,7 @@ TEST(Regress159140) {
TEST(Regress165495) {
+ if (!i::FLAG_incremental_marking) return;
i::FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
@@ -4070,7 +4082,7 @@ TEST(Regress165495) {
CHECK(f->is_compiled());
const int kAgingThreshold = 6;
for (int i = 0; i < kAgingThreshold; i++) {
- f->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2));
+ f->shared()->code()->MakeOlder();
}
CompileRun("f = null;");
@@ -4088,6 +4100,7 @@ TEST(Regress165495) {
TEST(Regress169209) {
+ if (!i::FLAG_incremental_marking) return;
i::FLAG_always_opt = false;
i::FLAG_stress_compaction = false;
i::FLAG_allow_natives_syntax = true;
@@ -4122,7 +4135,7 @@ TEST(Regress169209) {
CHECK(f->is_compiled());
const int kAgingThreshold = 6;
for (int i = 0; i < kAgingThreshold; i++) {
- f->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2));
+ f->shared()->code()->MakeOlder();
}
shared1 = inner_scope.CloseAndEscape(handle(f->shared(), isolate));
@@ -4147,7 +4160,7 @@ TEST(Regress169209) {
CHECK(f->is_compiled());
const int kAgingThreshold = 6;
for (int i = 0; i < kAgingThreshold; i++) {
- f->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2));
+ f->shared()->code()->MakeOlder();
}
shared2 = inner_scope.CloseAndEscape(handle(f->shared(), isolate));
@@ -4248,7 +4261,6 @@ TEST(Regress169928) {
#ifdef DEBUG
TEST(Regress513507) {
- i::FLAG_flush_optimized_code_cache = false;
i::FLAG_allow_natives_syntax = true;
i::FLAG_gc_global = true;
CcTest::InitializeVM();
@@ -4302,9 +4314,8 @@ TEST(Regress513507) {
}
#endif // DEBUG
-
TEST(Regress514122) {
- i::FLAG_flush_optimized_code_cache = false;
+ if (!i::FLAG_incremental_marking) return;
i::FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
@@ -4319,8 +4330,9 @@ TEST(Regress514122) {
Handle<SharedFunctionInfo> shared;
{
HandleScope inner_scope(isolate);
- CompileRun("function f() { return 1 }"
- "f(); %OptimizeFunctionOnNextCall(f); f();");
+ CompileRun(
+ "function f() { return 1 }"
+ "f(); %OptimizeFunctionOnNextCall(f); f();");
Handle<JSFunction> f = Handle<JSFunction>::cast(
v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
@@ -4333,8 +4345,9 @@ TEST(Regress514122) {
Handle<Code> code;
{
HandleScope inner_scope(isolate);
- CompileRun("function g() { return 2 }"
- "g(); %OptimizeFunctionOnNextCall(g); g();");
+ CompileRun(
+ "function g() { return 2 }"
+ "g(); %OptimizeFunctionOnNextCall(g); g();");
Handle<JSFunction> g = Handle<JSFunction>::cast(
v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
@@ -4395,9 +4408,7 @@ TEST(Regress514122) {
boomer->Print();
}
-
TEST(OptimizedCodeMapReuseEntries) {
- i::FLAG_flush_optimized_code_cache = false;
i::FLAG_allow_natives_syntax = true;
// BUG(v8:4598): Since TurboFan doesn't treat maps in code weakly, we can't
// run this test.
@@ -4503,9 +4514,7 @@ TEST(OptimizedCodeMapReuseEntries) {
}
}
-
TEST(Regress513496) {
- i::FLAG_flush_optimized_code_cache = false;
i::FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
@@ -4537,7 +4546,7 @@ TEST(Regress513496) {
CHECK(g->shared()->is_compiled());
const int kAgingThreshold = 6;
for (int i = 0; i < kAgingThreshold; i++) {
- g->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2));
+ g->shared()->code()->MakeOlder();
}
Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle(
@@ -4565,6 +4574,7 @@ TEST(Regress513496) {
TEST(LargeObjectSlotRecording) {
+ if (!i::FLAG_incremental_marking) return;
FLAG_manual_evacuation_candidates_selection = true;
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
@@ -4637,6 +4647,7 @@ TEST(DeferredHandles) {
TEST(IncrementalMarkingStepMakesBigProgressWithLargeObjects) {
+ if (!FLAG_incremental_marking) return;
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
CompileRun("function f(n) {"
@@ -5448,6 +5459,7 @@ TEST(WeakCell) {
TEST(WeakCellsWithIncrementalMarking) {
+ if (!FLAG_incremental_marking) return;
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
v8::internal::Heap* heap = CcTest::heap();
@@ -5719,6 +5731,7 @@ UNINITIALIZED_TEST(PromotionQueue) {
TEST(Regress388880) {
+ if (!FLAG_incremental_marking) return;
i::FLAG_expose_gc = true;
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
@@ -5766,6 +5779,7 @@ TEST(Regress388880) {
TEST(Regress3631) {
+ if (!FLAG_incremental_marking) return;
i::FLAG_expose_gc = true;
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
@@ -5899,6 +5913,7 @@ void CheckMapRetainingFor(int n) {
TEST(MapRetaining) {
+ if (!FLAG_incremental_marking) return;
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
CheckMapRetainingFor(FLAG_retain_maps_for_n_gc);
@@ -5963,8 +5978,7 @@ static void TestRightTrimFixedTypedArray(i::ExternalArrayType type,
Handle<FixedTypedArrayBase> array =
factory->NewFixedTypedArray(initial_length, type, true);
int old_size = array->size();
- heap->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(*array,
- elements_to_trim);
+ heap->RightTrimFixedArray(*array, elements_to_trim);
// Check that free space filler is at the right place and did not smash the
// array header.
@@ -6255,9 +6269,9 @@ static void RemoveCodeAndGC(const v8::FunctionCallbackInfo<v8::Value>& args) {
Isolate* isolate = CcTest::i_isolate();
Handle<Object> obj = v8::Utils::OpenHandle(*args[0]);
Handle<JSFunction> fun = Handle<JSFunction>::cast(obj);
+ fun->shared()->ClearBytecodeArray(); // Bytecode is code too.
fun->ReplaceCode(*isolate->builtins()->CompileLazy());
fun->shared()->ReplaceCode(*isolate->builtins()->CompileLazy());
- fun->shared()->ClearBytecodeArray(); // Bytecode is code too.
CcTest::CollectAllAvailableGarbage();
}
@@ -6384,50 +6398,13 @@ TEST(SharedFunctionInfoIterator) {
}
{
- SharedFunctionInfo::Iterator iterator(isolate);
+ SharedFunctionInfo::GlobalIterator iterator(isolate);
while (iterator.Next()) sfi_count--;
}
CHECK_EQ(0, sfi_count);
}
-
-template <typename T>
-static UniqueId MakeUniqueId(const Persistent<T>& p) {
- return UniqueId(reinterpret_cast<uintptr_t>(*v8::Utils::OpenPersistent(p)));
-}
-
-
-TEST(Regress519319) {
- CcTest::InitializeVM();
- v8::Isolate* isolate = CcTest::isolate();
- v8::HandleScope scope(isolate);
- Heap* heap = CcTest::heap();
- LocalContext context;
-
- v8::Persistent<Value> parent;
- v8::Persistent<Value> child;
-
- parent.Reset(isolate, v8::Object::New(isolate));
- child.Reset(isolate, v8::Object::New(isolate));
-
- heap::SimulateFullSpace(heap->old_space());
- CcTest::CollectGarbage(OLD_SPACE);
- {
- UniqueId id = MakeUniqueId(parent);
- isolate->SetObjectGroupId(parent, id);
- isolate->SetReferenceFromGroup(id, child);
- }
- // The CollectGarbage call above starts sweeper threads.
- // The crash will happen if the following two functions
- // are called before sweeping finishes.
- heap->StartIncrementalMarking(i::Heap::kNoGCFlags,
- i::GarbageCollectionReason::kTesting);
- heap->FinalizeIncrementalMarkingIfComplete(
- i::GarbageCollectionReason::kTesting);
-}
-
-
HEAP_TEST(Regress587004) {
FLAG_concurrent_sweeping = false;
#ifdef VERIFY_HEAP
@@ -6449,7 +6426,7 @@ HEAP_TEST(Regress587004) {
}
CcTest::CollectGarbage(OLD_SPACE);
heap::SimulateFullSpace(heap->old_space());
- heap->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(*array, N - 1);
+ heap->RightTrimFixedArray(*array, N - 1);
heap->mark_compact_collector()->EnsureSweepingCompleted();
ByteArray* byte_array;
const int M = 256;
@@ -6467,6 +6444,7 @@ HEAP_TEST(Regress587004) {
}
HEAP_TEST(Regress589413) {
+ if (!FLAG_incremental_marking) return;
FLAG_stress_compaction = true;
FLAG_manual_evacuation_candidates_selection = true;
FLAG_parallel_compaction = false;
@@ -6533,7 +6511,7 @@ HEAP_TEST(Regress589413) {
}
heap::SimulateIncrementalMarking(heap);
for (size_t j = 0; j < arrays.size(); j++) {
- heap->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(arrays[j], N - 1);
+ heap->RightTrimFixedArray(arrays[j], N - 1);
}
}
// Force allocation from the free list.
@@ -6542,6 +6520,7 @@ HEAP_TEST(Regress589413) {
}
TEST(Regress598319) {
+ if (!FLAG_incremental_marking) return;
// This test ensures that no white objects can cross the progress bar of large
// objects during incremental marking. It checks this by using Shift() during
// incremental marking.
@@ -6658,6 +6637,7 @@ TEST(Regress609761) {
}
TEST(Regress615489) {
+ if (!i::FLAG_incremental_marking) return;
FLAG_black_allocation = true;
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
@@ -6712,6 +6692,7 @@ class StaticOneByteResource : public v8::String::ExternalOneByteStringResource {
};
TEST(Regress631969) {
+ if (!FLAG_incremental_marking) return;
FLAG_manual_evacuation_candidates_selection = true;
FLAG_parallel_compaction = false;
FLAG_concurrent_sweeping = false;
@@ -6757,6 +6738,7 @@ TEST(Regress631969) {
}
TEST(LeftTrimFixedArrayInBlackArea) {
+ if (!i::FLAG_incremental_marking) return;
FLAG_black_allocation = true;
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
@@ -6795,6 +6777,7 @@ TEST(LeftTrimFixedArrayInBlackArea) {
}
TEST(ContinuousLeftTrimFixedArrayInBlackArea) {
+ if (!i::FLAG_incremental_marking) return;
FLAG_black_allocation = true;
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
@@ -6860,6 +6843,7 @@ TEST(ContinuousLeftTrimFixedArrayInBlackArea) {
}
TEST(ContinuousRightTrimFixedArrayInBlackArea) {
+ if (!i::FLAG_incremental_marking) return;
FLAG_black_allocation = true;
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
@@ -6898,19 +6882,19 @@ TEST(ContinuousRightTrimFixedArrayInBlackArea) {
// Trim it once by one word to make checking for white marking color uniform.
Address previous = end_address - kPointerSize;
- heap->RightTrimFixedArray<Heap::SEQUENTIAL_TO_SWEEPER>(*array, 1);
+ heap->RightTrimFixedArray(*array, 1);
HeapObject* filler = HeapObject::FromAddress(previous);
CHECK(filler->IsFiller());
- CHECK(Marking::IsImpossible(ObjectMarking::MarkBitFrom(previous)));
+ CHECK(Marking::IsImpossible(ObjectMarking::MarkBitFrom(filler)));
// Trim 10 times by one, two, and three word.
for (int i = 1; i <= 3; i++) {
for (int j = 0; j < 10; j++) {
previous -= kPointerSize * i;
- heap->RightTrimFixedArray<Heap::SEQUENTIAL_TO_SWEEPER>(*array, i);
+ heap->RightTrimFixedArray(*array, i);
HeapObject* filler = HeapObject::FromAddress(previous);
CHECK(filler->IsFiller());
- CHECK(Marking::IsWhite(ObjectMarking::MarkBitFrom(previous)));
+ CHECK(Marking::IsWhite(ObjectMarking::MarkBitFrom(filler)));
}
}
@@ -6918,6 +6902,7 @@ TEST(ContinuousRightTrimFixedArrayInBlackArea) {
}
TEST(Regress618958) {
+ if (!i::FLAG_incremental_marking) return;
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Heap* heap = CcTest::heap();
@@ -7057,5 +7042,57 @@ HEAP_TEST(Regress670675) {
DCHECK(marking->IsStopped());
}
+HEAP_TEST(Regress5831) {
+ CcTest::InitializeVM();
+ Heap* heap = CcTest::heap();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope handle_scope(isolate);
+
+ // Used to ensure that the first code space page remains filled.
+ Handle<FixedArray> array = isolate->factory()->NewFixedArray(32);
+
+ {
+ // Ensure that the first code space page is full.
+ CEntryStub stub(isolate, 1);
+ Handle<Code> code = stub.GetCode();
+
+ int i = 0;
+ array = FixedArray::SetAndGrow(array, i++, code);
+
+ while (heap->code_space()->FirstPage()->Contains(code->address())) {
+ code = isolate->factory()->CopyCode(code);
+ array = FixedArray::SetAndGrow(array, i++, code);
+ }
+ }
+
+ class ImmovableCEntryStub : public i::CEntryStub {
+ public:
+ explicit ImmovableCEntryStub(i::Isolate* isolate)
+ : i::CEntryStub(isolate, 3, i::kSaveFPRegs, i::kArgvOnStack, true) {}
+ bool NeedsImmovableCode() override { return true; }
+ };
+
+ ImmovableCEntryStub stub(isolate);
+
+ {
+ // Make sure the code object has not yet been generated.
+ Code* code;
+ CHECK(!stub.FindCodeInCache(&code));
+ }
+
+ // Fake a serializer run.
+ isolate->serializer_enabled_ = true;
+
+ // Generate the code.
+ Handle<Code> code = stub.GetCode();
+ CHECK(code->Size() <= i::kMaxRegularHeapObjectSize);
+ CHECK(!heap->code_space()->FirstPage()->Contains(code->address()));
+
+ // Ensure it's not in large object space.
+ MemoryChunk* chunk = MemoryChunk::FromAddress(code->address());
+ CHECK(chunk->owner()->identity() != LO_SPACE);
+ CHECK(chunk->NeverEvacuate());
+}
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/cctest/heap/test-incremental-marking.cc b/deps/v8/test/cctest/heap/test-incremental-marking.cc
index c659cecea7..642a3584e7 100644
--- a/deps/v8/test/cctest/heap/test-incremental-marking.cc
+++ b/deps/v8/test/cctest/heap/test-incremental-marking.cc
@@ -57,7 +57,7 @@ class MockPlatform : public v8::Platform {
platform_->CallIdleOnForegroundThread(isolate, task);
}
- bool IdleTasksEnabled(v8::Isolate* isolate) override { return true; }
+ bool IdleTasksEnabled(v8::Isolate* isolate) override { return false; }
bool PendingTask() { return task_ != nullptr; }
@@ -114,31 +114,5 @@ TEST(IncrementalMarkingUsingTasks) {
i::V8::SetPlatformForTesting(old_platform);
}
-
-TEST(IncrementalMarkingUsingIdleTasksAfterGC) {
- if (!i::FLAG_incremental_marking) return;
-
- CcTest::InitializeVM();
- v8::Platform* old_platform = i::V8::GetCurrentPlatform();
- MockPlatform platform(old_platform);
- i::V8::SetPlatformForTesting(&platform);
- i::heap::SimulateFullSpace(CcTest::heap()->old_space());
- CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
- // Perform any pending idle tasks.
- while (platform.PendingTask()) {
- platform.PerformTask();
- }
- CHECK(!platform.PendingTask());
- i::IncrementalMarking* marking = CcTest::heap()->incremental_marking();
- marking->Stop();
- marking->Start(i::GarbageCollectionReason::kTesting);
- CHECK(platform.PendingTask());
- while (platform.PendingTask()) {
- platform.PerformTask();
- }
- CHECK(marking->IsStopped());
- i::V8::SetPlatformForTesting(old_platform);
-}
-
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/cctest/heap/test-mark-compact.cc b/deps/v8/test/cctest/heap/test-mark-compact.cc
index 0788e26108..ee37d070ac 100644
--- a/deps/v8/test/cctest/heap/test-mark-compact.cc
+++ b/deps/v8/test/cctest/heap/test-mark-compact.cc
@@ -41,6 +41,8 @@
#include "src/full-codegen/full-codegen.h"
#include "src/global-handles.h"
+#include "src/heap/mark-compact-inl.h"
+#include "src/heap/mark-compact.h"
#include "test/cctest/cctest.h"
#include "test/cctest/heap/heap-tester.h"
#include "test/cctest/heap/heap-utils.h"
@@ -483,4 +485,36 @@ TEST(RegressJoinThreadsOnIsolateDeinit) {
}
}
+TEST(Regress5829) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ v8::HandleScope sc(CcTest::isolate());
+ Heap* heap = isolate->heap();
+ heap::SealCurrentObjects(heap);
+ i::MarkCompactCollector* collector = heap->mark_compact_collector();
+ i::IncrementalMarking* marking = heap->incremental_marking();
+ if (collector->sweeping_in_progress()) {
+ collector->EnsureSweepingCompleted();
+ }
+ CHECK(marking->IsMarking() || marking->IsStopped());
+ if (marking->IsStopped()) {
+ heap->StartIncrementalMarking(i::Heap::kNoGCFlags,
+ i::GarbageCollectionReason::kTesting);
+ }
+ CHECK(marking->IsMarking());
+ marking->StartBlackAllocationForTesting();
+ Handle<FixedArray> array = isolate->factory()->NewFixedArray(10, TENURED);
+ Address old_end = array->address() + array->Size();
+ // Right trim the array without clearing the mark bits.
+ array->set_length(9);
+ heap->CreateFillerObjectAt(old_end - kPointerSize, kPointerSize,
+ ClearRecordedSlots::kNo);
+ heap->old_space()->EmptyAllocationInfo();
+ LiveObjectIterator<kGreyObjects> it(Page::FromAddress(array->address()));
+ HeapObject* object = nullptr;
+ while ((object = it.Next()) != nullptr) {
+ CHECK(!object->IsFiller());
+ }
+}
+
#endif // __linux__ and !USE_SIMULATOR
diff --git a/deps/v8/test/cctest/heap/test-page-promotion.cc b/deps/v8/test/cctest/heap/test-page-promotion.cc
index 4673f2edcf..3207c26250 100644
--- a/deps/v8/test/cctest/heap/test-page-promotion.cc
+++ b/deps/v8/test/cctest/heap/test-page-promotion.cc
@@ -42,6 +42,7 @@ namespace v8 {
namespace internal {
UNINITIALIZED_TEST(PagePromotion_NewToOld) {
+ if (!i::FLAG_incremental_marking) return;
v8::Isolate* isolate = NewIsolateForPagePromotion();
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
{
diff --git a/deps/v8/test/cctest/interpreter/bytecode-expectations-printer.cc b/deps/v8/test/cctest/interpreter/bytecode-expectations-printer.cc
index f7a5bb9467..8f34308ee0 100644
--- a/deps/v8/test/cctest/interpreter/bytecode-expectations-printer.cc
+++ b/deps/v8/test/cctest/interpreter/bytecode-expectations-printer.cc
@@ -25,6 +25,21 @@ namespace v8 {
namespace internal {
namespace interpreter {
+static const char* NameForNativeContextIntrinsicIndex(uint32_t idx) {
+ switch (idx) {
+#define COMPARE_NATIVE_CONTEXT_INTRINSIC_IDX(NAME, Type, name) \
+ case Context::NAME: \
+ return #name;
+
+ NATIVE_CONTEXT_INTRINSIC_FUNCTIONS(COMPARE_NATIVE_CONTEXT_INTRINSIC_IDX)
+
+ default:
+ break;
+ }
+
+ return "UnknownIntrinsicIndex";
+}
+
// static
const char* const BytecodeExpectationsPrinter::kDefaultTopFunctionName =
"__genbckexp_wrapper__";
@@ -162,9 +177,15 @@ void BytecodeExpectationsPrinter::PrintBytecodeOperand(
case OperandType::kFlag8:
stream << bytecode_iterator.GetFlagOperand(op_index);
break;
- case OperandType::kIdx:
- stream << bytecode_iterator.GetIndexOperand(op_index);
+ case OperandType::kIdx: {
+ uint32_t idx = bytecode_iterator.GetIndexOperand(op_index);
+ if (bytecode == Bytecode::kCallJSRuntime && op_index == 0) {
+ stream << "%" << NameForNativeContextIntrinsicIndex(idx);
+ } else {
+ stream << idx;
+ }
break;
+ }
case OperandType::kUImm:
stream << bytecode_iterator.GetUnsignedImmediateOperand(op_index);
break;
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/ArrayLiterals.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/ArrayLiterals.golden
index 92cdcac1bf..2d57edf4a0 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/ArrayLiterals.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/ArrayLiterals.golden
@@ -18,7 +18,7 @@ bytecodes: [
/* 51 S> */ B(Return),
]
constant pool: [
- FIXED_ARRAY_TYPE,
+ CONSTANT_ELEMENTS_PAIR_TYPE,
]
handlers: [
]
@@ -42,13 +42,13 @@ bytecodes: [
/* 54 E> */ B(StaKeyedPropertySloppy), R(2), R(1), U8(3),
B(LdaSmi), U8(1),
B(Star), R(1),
- /* 57 E> */ B(AddSmi), U8(1), R(0), U8(2),
+ /* 59 E> */ B(AddSmi), U8(1), R(0), U8(2),
B(StaKeyedPropertySloppy), R(2), R(1), U8(3),
B(Ldar), R(2),
/* 66 S> */ B(Return),
]
constant pool: [
- FIXED_ARRAY_TYPE,
+ CONSTANT_ELEMENTS_PAIR_TYPE,
]
handlers: [
]
@@ -66,7 +66,7 @@ bytecodes: [
/* 62 S> */ B(Return),
]
constant pool: [
- FIXED_ARRAY_TYPE,
+ CONSTANT_ELEMENTS_PAIR_TYPE,
]
handlers: [
]
@@ -100,7 +100,7 @@ bytecodes: [
B(Star), R(4),
B(LdaZero),
B(Star), R(3),
- /* 66 E> */ B(AddSmi), U8(2), R(0), U8(4),
+ /* 68 E> */ B(AddSmi), U8(2), R(0), U8(4),
B(StaKeyedPropertySloppy), R(4), R(3), U8(5),
B(Ldar), R(4),
B(StaKeyedPropertySloppy), R(2), R(1), U8(7),
@@ -108,9 +108,9 @@ bytecodes: [
/* 77 S> */ B(Return),
]
constant pool: [
- FIXED_ARRAY_TYPE,
- FIXED_ARRAY_TYPE,
- FIXED_ARRAY_TYPE,
+ CONSTANT_ELEMENTS_PAIR_TYPE,
+ CONSTANT_ELEMENTS_PAIR_TYPE,
+ CONSTANT_ELEMENTS_PAIR_TYPE,
]
handlers: [
]
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/ArrayLiteralsWide.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/ArrayLiteralsWide.golden
index 6431d8adbe..1dcfc48cbc 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/ArrayLiteralsWide.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/ArrayLiteralsWide.golden
@@ -1043,7 +1043,7 @@ constant pool: [
HEAP_NUMBER_TYPE [1.23],
HEAP_NUMBER_TYPE [1.23],
HEAP_NUMBER_TYPE [1.23],
- FIXED_ARRAY_TYPE,
+ CONSTANT_ELEMENTS_PAIR_TYPE,
]
handlers: [
]
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/AssignmentsInBinaryExpression.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/AssignmentsInBinaryExpression.golden
index d36860174c..4ea65897ff 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/AssignmentsInBinaryExpression.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/AssignmentsInBinaryExpression.golden
@@ -74,11 +74,11 @@ bytecodes: [
/* 46 S> */ B(LdaSmi), U8(100),
B(Mov), R(0), R(1),
B(Star), R(0),
- /* 57 E> */ B(Add), R(1), U8(2),
+ /* 52 E> */ B(Add), R(1), U8(2),
B(Star), R(1),
B(LdaSmi), U8(101),
B(Star), R(0),
- /* 69 E> */ B(Add), R(1), U8(3),
+ /* 64 E> */ B(Add), R(1), U8(3),
B(Star), R(0),
/* 77 S> */ B(Nop),
/* 87 S> */ B(Return),
@@ -104,11 +104,11 @@ bytecodes: [
B(Star), R(0),
/* 46 S> */ B(LdaSmi), U8(56),
B(Star), R(0),
- /* 61 E> */ B(Sub), R(0), U8(2),
+ /* 59 E> */ B(Sub), R(0), U8(2),
B(Star), R(1),
B(LdaSmi), U8(57),
B(Star), R(0),
- /* 68 E> */ B(Add), R(1), U8(3),
+ /* 63 E> */ B(Add), R(1), U8(3),
B(Star), R(0),
/* 75 S> */ B(Inc), U8(4),
B(Star), R(0),
@@ -136,15 +136,15 @@ bytecodes: [
/* 76 S> */ B(LdaSmi), U8(1),
B(Mov), R(0), R(2),
B(Star), R(0),
- /* 61 E> */ B(Add), R(2), U8(2),
+ /* 56 E> */ B(Add), R(2), U8(2),
B(Star), R(2),
B(LdaSmi), U8(2),
B(Star), R(0),
- /* 71 E> */ B(Add), R(2), U8(3),
+ /* 66 E> */ B(Add), R(2), U8(3),
B(Star), R(2),
B(LdaSmi), U8(3),
B(Star), R(0),
- /* 81 E> */ B(Add), R(2), U8(4),
+ /* 76 E> */ B(Add), R(2), U8(4),
B(Star), R(1),
/* 87 S> */ B(Nop),
/* 97 S> */ B(Return),
@@ -170,15 +170,15 @@ bytecodes: [
/* 76 S> */ B(LdaSmi), U8(1),
B(Mov), R(0), R(1),
B(Star), R(0),
- /* 61 E> */ B(Add), R(1), U8(2),
+ /* 56 E> */ B(Add), R(1), U8(2),
B(Star), R(1),
B(LdaSmi), U8(2),
B(Star), R(0),
- /* 71 E> */ B(Add), R(1), U8(3),
+ /* 66 E> */ B(Add), R(1), U8(3),
B(Star), R(1),
B(LdaSmi), U8(3),
B(Star), R(0),
- /* 81 E> */ B(Add), R(1), U8(4),
+ /* 76 E> */ B(Add), R(1), U8(4),
B(Star), R(0),
/* 87 S> */ B(Nop),
/* 97 S> */ B(Return),
@@ -205,29 +205,29 @@ bytecodes: [
/* 54 S> */ B(LdaSmi), U8(1),
B(Mov), R(0), R(2),
B(Star), R(0),
- /* 68 E> */ B(Add), R(2), U8(2),
+ /* 63 E> */ B(Add), R(2), U8(2),
B(Star), R(2),
- /* 76 E> */ B(AddSmi), U8(1), R(0), U8(3),
+ /* 78 E> */ B(AddSmi), U8(1), R(0), U8(3),
B(Star), R(3),
B(LdaSmi), U8(2),
B(Star), R(1),
- /* 88 E> */ B(Mul), R(3), U8(4),
- B(Add), R(2), U8(5),
+ /* 83 E> */ B(Mul), R(3), U8(4),
+ /* 73 E> */ B(Add), R(2), U8(5),
B(Star), R(2),
B(LdaSmi), U8(3),
B(Star), R(1),
- /* 98 E> */ B(Add), R(2), U8(6),
+ /* 93 E> */ B(Add), R(2), U8(6),
B(Star), R(2),
B(LdaSmi), U8(4),
B(Star), R(0),
- /* 108 E> */ B(Add), R(2), U8(7),
+ /* 103 E> */ B(Add), R(2), U8(7),
B(Star), R(2),
B(LdaSmi), U8(5),
B(Star), R(1),
- /* 118 E> */ B(Add), R(2), U8(8),
+ /* 113 E> */ B(Add), R(2), U8(8),
B(Star), R(2),
B(Ldar), R(1),
- /* 125 E> */ B(Add), R(2), U8(9),
+ /* 123 E> */ B(Add), R(2), U8(9),
/* 128 S> */ B(Return),
]
constant pool: [
@@ -250,7 +250,7 @@ bytecodes: [
/* 46 S> */ B(LdaSmi), U8(1),
B(Star), R(1),
B(Ldar), R(0),
- /* 57 E> */ B(Add), R(1), U8(2),
+ /* 55 E> */ B(Add), R(1), U8(2),
B(Star), R(1),
B(Ldar), R(0),
B(ToNumber), R(2),
@@ -258,12 +258,12 @@ bytecodes: [
B(Inc), U8(3),
B(Star), R(0),
B(Ldar), R(2),
- /* 63 E> */ B(Add), R(1), U8(4),
+ /* 59 E> */ B(Add), R(1), U8(4),
B(Star), R(1),
B(Ldar), R(0),
B(Inc), U8(5),
B(Star), R(0),
- /* 72 E> */ B(Add), R(1), U8(6),
+ /* 67 E> */ B(Add), R(1), U8(6),
/* 76 S> */ B(Return),
]
constant pool: [
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/BasicLoops.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/BasicLoops.golden
index 1cbd05fcea..d0c7f4934c 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/BasicLoops.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/BasicLoops.golden
@@ -63,7 +63,7 @@ snippet: "
"
frame size: 2
parameter count: 1
-bytecode array length: 53
+bytecode array length: 54
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero),
@@ -72,12 +72,13 @@ bytecodes: [
B(Star), R(1),
/* 65 S> */ B(LdaSmi), U8(10),
/* 65 E> */ B(TestLessThan), R(0), U8(2),
- B(JumpIfFalse), U8(37),
+ B(JumpIfFalse), U8(38),
/* 56 E> */ B(StackCheck),
/* 75 S> */ B(LdaSmi), U8(12),
- B(Mul), R(1), U8(3),
+ /* 81 E> */ B(Mul), R(1), U8(3),
B(Star), R(1),
- /* 89 S> */ B(AddSmi), U8(1), R(0), U8(4),
+ /* 89 S> */ B(LdaSmi), U8(1),
+ /* 95 E> */ B(Add), R(0), U8(4),
B(Star), R(0),
/* 102 S> */ B(LdaSmi), U8(3),
/* 108 E> */ B(TestEqual), R(0), U8(5),
@@ -87,7 +88,7 @@ bytecodes: [
/* 132 E> */ B(TestEqual), R(0), U8(6),
B(JumpIfFalse), U8(4),
/* 138 S> */ B(Jump), U8(5),
- B(JumpLoop), U8(-39), U8(0),
+ B(JumpLoop), U8(-40), U8(0),
/* 147 S> */ B(Ldar), R(1),
/* 157 S> */ B(Return),
]
@@ -111,7 +112,7 @@ snippet: "
"
frame size: 1
parameter count: 1
-bytecode array length: 61
+bytecode array length: 62
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero),
@@ -120,26 +121,27 @@ bytecodes: [
/* 62 S> */ B(LdaZero),
/* 68 E> */ B(TestLessThan), R(0), U8(2),
B(JumpIfFalse), U8(4),
- /* 73 S> */ B(Jump), U8(44),
+ /* 73 S> */ B(Jump), U8(45),
/* 85 S> */ B(LdaSmi), U8(3),
/* 91 E> */ B(TestEqual), R(0), U8(3),
B(JumpIfFalse), U8(4),
- /* 97 S> */ B(Jump), U8(38),
+ /* 97 S> */ B(Jump), U8(39),
/* 106 S> */ B(LdaSmi), U8(4),
/* 112 E> */ B(TestEqual), R(0), U8(4),
B(JumpIfFalse), U8(4),
- /* 118 S> */ B(Jump), U8(29),
+ /* 118 S> */ B(Jump), U8(30),
/* 127 S> */ B(LdaSmi), U8(10),
/* 133 E> */ B(TestEqual), R(0), U8(5),
B(JumpIfFalse), U8(4),
- /* 140 S> */ B(Jump), U8(17),
+ /* 140 S> */ B(Jump), U8(18),
/* 152 S> */ B(LdaSmi), U8(5),
/* 158 E> */ B(TestEqual), R(0), U8(6),
B(JumpIfFalse), U8(4),
- /* 164 S> */ B(Jump), U8(11),
- /* 173 S> */ B(AddSmi), U8(1), R(0), U8(7),
+ /* 164 S> */ B(Jump), U8(12),
+ /* 173 S> */ B(LdaSmi), U8(1),
+ /* 179 E> */ B(Add), R(0), U8(7),
B(Star), R(0),
- B(JumpLoop), U8(-51), U8(0),
+ B(JumpLoop), U8(-52), U8(0),
/* 186 S> */ B(Ldar), R(0),
/* 196 S> */ B(Return),
]
@@ -163,7 +165,7 @@ snippet: "
"
frame size: 1
parameter count: 1
-bytecode array length: 42
+bytecode array length: 44
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero),
@@ -171,16 +173,18 @@ bytecodes: [
/* 45 E> */ B(StackCheck),
/* 71 S> */ B(LdaSmi), U8(3),
/* 71 E> */ B(TestLessThan), R(0), U8(2),
- B(JumpIfFalse), U8(21),
+ B(JumpIfFalse), U8(22),
/* 62 E> */ B(StackCheck),
/* 82 S> */ B(LdaSmi), U8(2),
/* 88 E> */ B(TestEqual), R(0), U8(3),
B(JumpIfFalse), U8(4),
- /* 94 S> */ B(Jump), U8(11),
- /* 105 S> */ B(AddSmi), U8(1), R(0), U8(4),
+ /* 94 S> */ B(Jump), U8(12),
+ /* 105 S> */ B(LdaSmi), U8(1),
+ /* 111 E> */ B(Add), R(0), U8(4),
B(Star), R(0),
- B(JumpLoop), U8(-23), U8(1),
- /* 122 S> */ B(AddSmi), U8(1), R(0), U8(5),
+ B(JumpLoop), U8(-24), U8(1),
+ /* 122 S> */ B(LdaSmi), U8(1),
+ /* 128 E> */ B(Add), R(0), U8(5),
B(Star), R(0),
/* 135 S> */ B(Jump), U8(2),
/* 144 S> */ B(Ldar), R(0),
@@ -203,7 +207,7 @@ snippet: "
"
frame size: 2
parameter count: 1
-bytecode array length: 33
+bytecode array length: 34
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(10),
@@ -211,14 +215,15 @@ bytecodes: [
/* 54 S> */ B(LdaSmi), U8(1),
B(Star), R(1),
/* 64 S> */ B(Ldar), R(0),
- B(JumpIfToBooleanFalse), U8(19),
+ B(JumpIfToBooleanFalse), U8(20),
/* 57 E> */ B(StackCheck),
/* 71 S> */ B(LdaSmi), U8(12),
- B(Mul), R(1), U8(2),
+ /* 77 E> */ B(Mul), R(1), U8(2),
B(Star), R(1),
- /* 85 S> */ B(SubSmi), U8(1), R(0), U8(3),
+ /* 85 S> */ B(LdaSmi), U8(1),
+ /* 91 E> */ B(Sub), R(0), U8(3),
B(Star), R(0),
- B(JumpLoop), U8(-18), U8(0),
+ B(JumpLoop), U8(-19), U8(0),
/* 98 S> */ B(Ldar), R(1),
/* 108 S> */ B(Return),
]
@@ -240,7 +245,7 @@ snippet: "
"
frame size: 2
parameter count: 1
-bytecode array length: 53
+bytecode array length: 54
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero),
@@ -249,22 +254,23 @@ bytecodes: [
B(Star), R(1),
/* 56 E> */ B(StackCheck),
/* 63 S> */ B(LdaSmi), U8(10),
- B(Mul), R(1), U8(2),
+ /* 69 E> */ B(Mul), R(1), U8(2),
B(Star), R(1),
/* 77 S> */ B(LdaSmi), U8(5),
/* 83 E> */ B(TestEqual), R(0), U8(3),
B(JumpIfFalse), U8(4),
- /* 89 S> */ B(Jump), U8(27),
+ /* 89 S> */ B(Jump), U8(28),
/* 98 S> */ B(LdaSmi), U8(6),
/* 104 E> */ B(TestEqual), R(0), U8(4),
B(JumpIfFalse), U8(4),
- /* 110 S> */ B(Jump), U8(8),
- /* 122 S> */ B(AddSmi), U8(1), R(0), U8(5),
+ /* 110 S> */ B(Jump), U8(9),
+ /* 122 S> */ B(LdaSmi), U8(1),
+ /* 128 E> */ B(Add), R(0), U8(5),
B(Star), R(0),
/* 144 S> */ B(LdaSmi), U8(10),
/* 144 E> */ B(TestLessThan), R(0), U8(6),
B(JumpIfFalse), U8(5),
- B(JumpLoop), U8(-39), U8(0),
+ B(JumpLoop), U8(-40), U8(0),
/* 151 S> */ B(Ldar), R(1),
/* 161 S> */ B(Return),
]
@@ -285,7 +291,7 @@ snippet: "
"
frame size: 2
parameter count: 1
-bytecode array length: 31
+bytecode array length: 32
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(10),
@@ -294,12 +300,13 @@ bytecodes: [
B(Star), R(1),
/* 57 E> */ B(StackCheck),
/* 64 S> */ B(LdaSmi), U8(12),
- B(Mul), R(1), U8(2),
+ /* 70 E> */ B(Mul), R(1), U8(2),
B(Star), R(1),
- /* 78 S> */ B(SubSmi), U8(1), R(0), U8(3),
+ /* 78 S> */ B(LdaSmi), U8(1),
+ /* 84 E> */ B(Sub), R(0), U8(3),
B(Star), R(0),
/* 98 S> */ B(JumpIfToBooleanFalse), U8(5),
- B(JumpLoop), U8(-16), U8(0),
+ B(JumpLoop), U8(-17), U8(0),
/* 102 S> */ B(Ldar), R(1),
/* 112 S> */ B(Return),
]
@@ -321,7 +328,7 @@ snippet: "
"
frame size: 2
parameter count: 1
-bytecode array length: 43
+bytecode array length: 44
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero),
@@ -330,13 +337,14 @@ bytecodes: [
B(Star), R(1),
/* 56 E> */ B(StackCheck),
/* 63 S> */ B(LdaSmi), U8(10),
- B(Mul), R(1), U8(2),
+ /* 69 E> */ B(Mul), R(1), U8(2),
B(Star), R(1),
/* 77 S> */ B(LdaSmi), U8(5),
/* 83 E> */ B(TestEqual), R(0), U8(3),
B(JumpIfFalse), U8(4),
- /* 89 S> */ B(Jump), U8(17),
- /* 98 S> */ B(AddSmi), U8(1), R(0), U8(4),
+ /* 89 S> */ B(Jump), U8(18),
+ /* 98 S> */ B(LdaSmi), U8(1),
+ /* 104 E> */ B(Add), R(0), U8(4),
B(Star), R(0),
/* 111 S> */ B(LdaSmi), U8(6),
/* 117 E> */ B(TestEqual), R(0), U8(5),
@@ -363,7 +371,7 @@ snippet: "
"
frame size: 2
parameter count: 1
-bytecode array length: 46
+bytecode array length: 47
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero),
@@ -372,19 +380,20 @@ bytecodes: [
B(Star), R(1),
/* 56 E> */ B(StackCheck),
/* 63 S> */ B(LdaSmi), U8(10),
- B(Mul), R(1), U8(2),
+ /* 69 E> */ B(Mul), R(1), U8(2),
B(Star), R(1),
/* 77 S> */ B(LdaSmi), U8(5),
/* 83 E> */ B(TestEqual), R(0), U8(3),
B(JumpIfFalse), U8(4),
- /* 89 S> */ B(Jump), U8(20),
- /* 98 S> */ B(AddSmi), U8(1), R(0), U8(4),
+ /* 89 S> */ B(Jump), U8(21),
+ /* 98 S> */ B(LdaSmi), U8(1),
+ /* 104 E> */ B(Add), R(0), U8(4),
B(Star), R(0),
/* 111 S> */ B(LdaSmi), U8(6),
/* 117 E> */ B(TestEqual), R(0), U8(5),
B(JumpIfFalse), U8(4),
/* 123 S> */ B(Jump), U8(2),
- B(JumpLoop), U8(-32), U8(0),
+ B(JumpLoop), U8(-33), U8(0),
/* 149 S> */ B(Ldar), R(1),
/* 159 S> */ B(Return),
]
@@ -404,7 +413,7 @@ snippet: "
"
frame size: 1
parameter count: 1
-bytecode array length: 34
+bytecode array length: 35
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero),
@@ -413,14 +422,15 @@ bytecodes: [
/* 58 S> */ B(LdaSmi), U8(1),
/* 64 E> */ B(TestEqual), R(0), U8(2),
B(JumpIfFalse), U8(4),
- /* 70 S> */ B(Jump), U8(20),
+ /* 70 S> */ B(Jump), U8(21),
/* 79 S> */ B(LdaSmi), U8(2),
/* 85 E> */ B(TestEqual), R(0), U8(3),
B(JumpIfFalse), U8(4),
- /* 91 S> */ B(Jump), U8(8),
- /* 103 S> */ B(AddSmi), U8(1), R(0), U8(4),
+ /* 91 S> */ B(Jump), U8(9),
+ /* 103 S> */ B(LdaSmi), U8(1),
+ /* 109 E> */ B(Add), R(0), U8(4),
B(Star), R(0),
- B(JumpLoop), U8(-25), U8(0),
+ B(JumpLoop), U8(-26), U8(0),
B(LdaUndefined),
/* 116 S> */ B(Return),
]
@@ -439,7 +449,7 @@ snippet: "
"
frame size: 1
parameter count: 1
-bytecode array length: 34
+bytecode array length: 35
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 47 S> */ B(LdaZero),
@@ -448,14 +458,15 @@ bytecodes: [
/* 56 S> */ B(LdaSmi), U8(1),
/* 62 E> */ B(TestEqual), R(0), U8(2),
B(JumpIfFalse), U8(4),
- /* 68 S> */ B(Jump), U8(20),
+ /* 68 S> */ B(Jump), U8(21),
/* 77 S> */ B(LdaSmi), U8(2),
/* 83 E> */ B(TestEqual), R(0), U8(3),
B(JumpIfFalse), U8(4),
- /* 89 S> */ B(Jump), U8(8),
- /* 101 S> */ B(AddSmi), U8(1), R(0), U8(4),
+ /* 89 S> */ B(Jump), U8(9),
+ /* 101 S> */ B(LdaSmi), U8(1),
+ /* 107 E> */ B(Add), R(0), U8(4),
B(Star), R(0),
- B(JumpLoop), U8(-25), U8(0),
+ B(JumpLoop), U8(-26), U8(0),
B(LdaUndefined),
/* 114 S> */ B(Return),
]
@@ -474,7 +485,7 @@ snippet: "
"
frame size: 1
parameter count: 1
-bytecode array length: 34
+bytecode array length: 35
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero),
@@ -483,14 +494,15 @@ bytecodes: [
/* 68 S> */ B(LdaSmi), U8(1),
/* 74 E> */ B(TestEqual), R(0), U8(3),
B(JumpIfFalse), U8(4),
- /* 80 S> */ B(Jump), U8(20),
+ /* 80 S> */ B(Jump), U8(21),
/* 89 S> */ B(LdaSmi), U8(2),
/* 95 E> */ B(TestEqual), R(0), U8(4),
B(JumpIfFalse), U8(4),
/* 101 S> */ B(Jump), U8(2),
- /* 55 S> */ B(AddSmi), U8(1), R(0), U8(2),
+ /* 55 S> */ B(LdaSmi), U8(1),
+ /* 59 E> */ B(Add), R(0), U8(2),
B(Star), R(0),
- B(JumpLoop), U8(-25), U8(0),
+ B(JumpLoop), U8(-26), U8(0),
B(LdaUndefined),
/* 113 S> */ B(Return),
]
@@ -508,7 +520,7 @@ snippet: "
"
frame size: 1
parameter count: 1
-bytecode array length: 34
+bytecode array length: 35
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 47 S> */ B(LdaZero),
@@ -517,14 +529,15 @@ bytecodes: [
/* 66 S> */ B(LdaSmi), U8(1),
/* 72 E> */ B(TestEqual), R(0), U8(3),
B(JumpIfFalse), U8(4),
- /* 78 S> */ B(Jump), U8(20),
+ /* 78 S> */ B(Jump), U8(21),
/* 87 S> */ B(LdaSmi), U8(2),
/* 93 E> */ B(TestEqual), R(0), U8(4),
B(JumpIfFalse), U8(4),
/* 99 S> */ B(Jump), U8(2),
- /* 53 S> */ B(AddSmi), U8(1), R(0), U8(2),
+ /* 53 S> */ B(LdaSmi), U8(1),
+ /* 57 E> */ B(Add), R(0), U8(2),
B(Star), R(0),
- B(JumpLoop), U8(-25), U8(0),
+ B(JumpLoop), U8(-26), U8(0),
B(LdaUndefined),
/* 111 S> */ B(Return),
]
@@ -543,7 +556,7 @@ snippet: "
"
frame size: 2
parameter count: 1
-bytecode array length: 34
+bytecode array length: 36
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero),
@@ -552,14 +565,16 @@ bytecodes: [
B(Star), R(1),
/* 63 S> */ B(LdaSmi), U8(100),
/* 63 E> */ B(TestLessThan), R(1), U8(2),
- B(JumpIfFalse), U8(20),
+ B(JumpIfFalse), U8(22),
/* 45 E> */ B(StackCheck),
- /* 85 S> */ B(AddSmi), U8(1), R(0), U8(4),
+ /* 85 S> */ B(LdaSmi), U8(1),
+ /* 91 E> */ B(Add), R(0), U8(4),
B(Star), R(0),
/* 98 S> */ B(Jump), U8(2),
- /* 72 S> */ B(AddSmi), U8(1), R(1), U8(3),
+ /* 72 S> */ B(LdaSmi), U8(1),
+ /* 76 E> */ B(Add), R(1), U8(3),
B(Star), R(1),
- B(JumpLoop), U8(-22), U8(0),
+ B(JumpLoop), U8(-24), U8(0),
B(LdaUndefined),
/* 110 S> */ B(Return),
]
@@ -589,7 +604,7 @@ bytecodes: [
B(JumpIfToBooleanFalse), U8(19),
/* 45 E> */ B(StackCheck),
/* 74 S> */ B(LdaSmi), U8(12),
- B(Mul), R(0), U8(3),
+ /* 80 E> */ B(Mul), R(0), U8(3),
B(Star), R(0),
/* 67 S> */ B(Ldar), R(1),
B(Dec), U8(2),
@@ -639,7 +654,7 @@ snippet: "
"
frame size: 2
parameter count: 1
-bytecode array length: 35
+bytecode array length: 36
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero),
@@ -647,7 +662,8 @@ bytecodes: [
/* 58 S> */ B(LdaZero),
B(Star), R(1),
/* 45 E> */ B(StackCheck),
- /* 76 S> */ B(AddSmi), U8(1), R(0), U8(3),
+ /* 76 S> */ B(LdaSmi), U8(1),
+ /* 82 E> */ B(Add), R(0), U8(3),
B(Star), R(0),
/* 89 S> */ B(LdaSmi), U8(20),
/* 95 E> */ B(TestEqual), R(0), U8(4),
@@ -656,7 +672,7 @@ bytecodes: [
/* 69 S> */ B(Ldar), R(1),
B(Inc), U8(2),
B(Star), R(1),
- B(JumpLoop), U8(-22), U8(0),
+ B(JumpLoop), U8(-23), U8(0),
/* 112 S> */ B(Ldar), R(0),
/* 122 S> */ B(Return),
]
@@ -679,20 +695,20 @@ snippet: "
"
frame size: 4
parameter count: 1
-bytecode array length: 53
+bytecode array length: 54
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero),
B(Star), R(1),
/* 52 S> */ B(Ldar), R(1),
- B(JumpIfToBooleanFalse), U8(45),
+ B(JumpIfToBooleanFalse), U8(46),
/* 45 E> */ B(StackCheck),
B(Ldar), R(closure),
B(CreateBlockContext), U8(0),
B(PushContext), R(3),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
- B(CreateClosure), U8(1), U8(2),
+ B(CreateClosure), U8(1), U8(2), U8(2),
B(Star), R(0),
/* 73 S> */ B(LdaSmi), U8(1),
/* 73 E> */ B(StaCurrentContextSlot), U8(4),
@@ -703,10 +719,10 @@ bytecodes: [
B(PopContext), R(3),
B(Jump), U8(10),
/* 126 S> */ B(LdaCurrentContextSlot), U8(4),
- B(Inc), U8(2),
+ B(Inc), U8(3),
/* 127 E> */ B(StaCurrentContextSlot), U8(4),
B(PopContext), R(3),
- B(JumpLoop), U8(-44), U8(0),
+ B(JumpLoop), U8(-45), U8(0),
B(LdaUndefined),
/* 137 S> */ B(Return),
]
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/BreakableBlocks.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/BreakableBlocks.golden
index 9058fb8ad1..ce343d01b3 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/BreakableBlocks.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/BreakableBlocks.golden
@@ -17,12 +17,13 @@ snippet: "
"
frame size: 1
parameter count: 1
-bytecode array length: 15
+bytecode array length: 16
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero),
B(Star), R(0),
- /* 56 S> */ B(AddSmi), U8(1), R(0), U8(2),
+ /* 56 S> */ B(LdaSmi), U8(1),
+ /* 62 E> */ B(Add), R(0), U8(2),
B(Star), R(0),
/* 69 S> */ B(Jump), U8(2),
/* 97 S> */ B(Ldar), R(0),
@@ -69,7 +70,7 @@ bytecodes: [
B(Inc), U8(6),
B(Star), R(0),
/* 142 S> */ B(Ldar), R(2),
- /* 150 E> */ B(Add), R(1), U8(7),
+ /* 148 E> */ B(Add), R(1), U8(7),
B(Star), R(3),
B(LdaSmi), U8(12),
/* 152 E> */ B(TestEqual), R(3), U8(8),
@@ -101,7 +102,7 @@ snippet: "
"
frame size: 3
parameter count: 1
-bytecode array length: 30
+bytecode array length: 31
bytecodes: [
/* 30 E> */ B(StackCheck),
B(Ldar), R(closure),
@@ -109,7 +110,7 @@ bytecodes: [
B(PushContext), R(2),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
- B(CreateClosure), U8(1), U8(2),
+ B(CreateClosure), U8(1), U8(2), U8(2),
B(Star), R(0),
/* 53 S> */ B(LdaSmi), U8(10),
/* 53 E> */ B(StaCurrentContextSlot), U8(4),
@@ -142,7 +143,7 @@ snippet: "
"
frame size: 4
parameter count: 1
-bytecode array length: 53
+bytecode array length: 54
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(2),
@@ -156,7 +157,7 @@ bytecodes: [
B(PushContext), R(3),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
- B(CreateClosure), U8(1), U8(2),
+ B(CreateClosure), U8(1), U8(2), U8(2),
B(Star), R(0),
/* 76 S> */ B(LdaSmi), U8(2),
/* 76 E> */ B(StaCurrentContextSlot), U8(4),
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/CallGlobal.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/CallGlobal.golden
index 40be0533c1..beb9a30222 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/CallGlobal.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/CallGlobal.golden
@@ -14,17 +14,18 @@ snippet: "
"
frame size: 2
parameter count: 1
-bytecode array length: 14
+bytecode array length: 15
bytecodes: [
/* 27 E> */ B(StackCheck),
/* 32 S> */ B(LdaUndefined),
B(Star), R(1),
- B(LdaGlobal), U8(4),
+ B(LdaGlobal), U8(0), U8(4),
B(Star), R(0),
/* 39 E> */ B(Call), R(0), R(1), U8(1), U8(2),
/* 44 S> */ B(Return),
]
constant pool: [
+ ONE_BYTE_INTERNALIZED_STRING_TYPE ["t"],
]
handlers: [
]
@@ -37,12 +38,12 @@ snippet: "
"
frame size: 5
parameter count: 1
-bytecode array length: 26
+bytecode array length: 27
bytecodes: [
/* 34 E> */ B(StackCheck),
/* 39 S> */ B(LdaUndefined),
B(Star), R(1),
- B(LdaGlobal), U8(4),
+ B(LdaGlobal), U8(0), U8(4),
B(Star), R(0),
B(LdaSmi), U8(1),
B(Star), R(2),
@@ -54,6 +55,7 @@ bytecodes: [
/* 58 S> */ B(Return),
]
constant pool: [
+ ONE_BYTE_INTERNALIZED_STRING_TYPE ["t"],
]
handlers: [
]
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/CallLookupSlot.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/CallLookupSlot.golden
index e05419fbff..cad09007e5 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/CallLookupSlot.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/CallLookupSlot.golden
@@ -11,7 +11,7 @@ snippet: "
"
frame size: 10
parameter count: 1
-bytecode array length: 81
+bytecode array length: 82
bytecodes: [
B(CreateFunctionContext), U8(3),
B(PushContext), R(0),
@@ -22,11 +22,11 @@ bytecodes: [
B(Ldar), R(new_target),
B(StaCurrentContextSlot), U8(5),
/* 30 E> */ B(StackCheck),
- /* 34 S> */ B(CreateClosure), U8(0), U8(2),
+ /* 34 S> */ B(CreateClosure), U8(0), U8(2), U8(2),
/* 36 E> */ B(StaLookupSlotSloppy), U8(1),
/* 52 S> */ B(LdaUndefined),
B(Star), R(2),
- /* 52 E> */ B(LdaLookupGlobalSlot), U8(2), U8(4), U8(1),
+ /* 52 E> */ B(LdaLookupGlobalSlot), U8(2), U8(5), U8(1),
B(Star), R(1),
B(LdaConstant), U8(3),
B(Star), R(3),
@@ -41,12 +41,12 @@ bytecodes: [
B(Mov), R(closure), R(6),
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), U8(6),
B(Star), R(1),
- /* 52 E> */ B(Call), R(1), R(2), U8(2), U8(2),
+ /* 52 E> */ B(Call), R(1), R(2), U8(2), U8(3),
/* 62 S> */ B(LdaUndefined),
B(Star), R(2),
- /* 69 E> */ B(LdaLookupGlobalSlot), U8(1), U8(8), U8(1),
+ /* 69 E> */ B(LdaLookupGlobalSlot), U8(1), U8(9), U8(1),
B(Star), R(1),
- /* 69 E> */ B(Call), R(1), R(2), U8(1), U8(6),
+ /* 69 E> */ B(Call), R(1), R(2), U8(1), U8(7),
/* 74 S> */ B(Return),
]
constant pool: [
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/CallNew.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/CallNew.golden
index eb5b0630f4..f60f73e065 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/CallNew.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/CallNew.golden
@@ -14,15 +14,16 @@ snippet: "
"
frame size: 1
parameter count: 1
-bytecode array length: 11
+bytecode array length: 12
bytecodes: [
/* 45 E> */ B(StackCheck),
- /* 50 S> */ B(LdaGlobal), U8(4),
+ /* 50 S> */ B(LdaGlobal), U8(0), U8(4),
B(Star), R(0),
/* 57 E> */ B(New), R(0), R(0), U8(0), U8(2),
/* 68 S> */ B(Return),
]
constant pool: [
+ ONE_BYTE_INTERNALIZED_STRING_TYPE ["bar"],
]
handlers: [
]
@@ -35,10 +36,10 @@ snippet: "
"
frame size: 2
parameter count: 1
-bytecode array length: 17
+bytecode array length: 18
bytecodes: [
/* 58 E> */ B(StackCheck),
- /* 63 S> */ B(LdaGlobal), U8(4),
+ /* 63 S> */ B(LdaGlobal), U8(0), U8(4),
B(Star), R(0),
B(LdaSmi), U8(3),
B(Star), R(1),
@@ -47,6 +48,7 @@ bytecodes: [
/* 82 S> */ B(Return),
]
constant pool: [
+ ONE_BYTE_INTERNALIZED_STRING_TYPE ["bar"],
]
handlers: [
]
@@ -64,10 +66,10 @@ snippet: "
"
frame size: 4
parameter count: 1
-bytecode array length: 25
+bytecode array length: 26
bytecodes: [
/* 100 E> */ B(StackCheck),
- /* 105 S> */ B(LdaGlobal), U8(4),
+ /* 105 S> */ B(LdaGlobal), U8(0), U8(4),
B(Star), R(0),
B(LdaSmi), U8(3),
B(Star), R(1),
@@ -80,6 +82,7 @@ bytecodes: [
/* 130 S> */ B(Return),
]
constant pool: [
+ ONE_BYTE_INTERNALIZED_STRING_TYPE ["bar"],
]
handlers: [
]
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/CallRuntime.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/CallRuntime.golden
index 149e668291..31e697590e 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/CallRuntime.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/CallRuntime.golden
@@ -79,11 +79,11 @@ bytecodes: [
B(Star), R(0),
B(CreateArrayLiteral), U8(0), U8(0), U8(9),
B(Star), R(1),
- B(CallJSRuntime), U8(154), R(0), U8(2),
+ B(CallJSRuntime), U8(%spread_iterable), R(0), U8(2),
/* 44 S> */ B(Return),
]
constant pool: [
- FIXED_ARRAY_TYPE,
+ CONSTANT_ELEMENTS_PAIR_TYPE,
]
handlers: [
]
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/ClassAndSuperClass.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/ClassAndSuperClass.golden
index 174641bc74..0c41685b86 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/ClassAndSuperClass.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/ClassAndSuperClass.golden
@@ -36,7 +36,7 @@ bytecodes: [
B(Star), R(1),
/* 117 E> */ B(Call), R(1), R(this), U8(1), U8(2),
B(Star), R(1),
- B(AddSmi), U8(1), R(1), U8(8),
+ /* 126 E> */ B(AddSmi), U8(1), R(1), U8(8),
/* 131 S> */ B(Return),
]
constant pool: [
@@ -107,14 +107,14 @@ snippet: "
"
frame size: 4
parameter count: 1
-bytecode array length: 82
+bytecode array length: 75
bytecodes: [
B(Mov), R(closure), R(1),
B(Mov), R(new_target), R(0),
B(Ldar), R(new_target),
/* 113 E> */ B(StackCheck),
- /* 118 S> */ B(CallRuntime), U16(Runtime::k_GetSuperConstructor), R(1), U8(1),
- B(Star), R(2),
+ /* 118 S> */ B(Ldar), R(1),
+ B(GetSuperConstructor), R(2),
B(LdaSmi), U8(1),
B(Star), R(3),
B(Ldar), R(0),
@@ -122,10 +122,8 @@ bytecodes: [
B(Star), R(2),
B(Ldar), R(this),
B(JumpIfNotHole), U8(4),
- B(Jump), U8(11),
- B(LdaConstant), U8(0),
- B(Star), R(3),
- /* 118 E> */ B(CallRuntime), U16(Runtime::kThrowReferenceError), R(3), U8(1),
+ B(Jump), U8(7),
+ /* 118 E> */ B(CallRuntime), U16(Runtime::kThrowSuperAlreadyCalledError), R(0), U8(0),
B(Mov), R(2), R(this),
/* 128 S> */ B(Ldar), R(this),
B(JumpIfNotHole), U8(11),
@@ -162,25 +160,23 @@ snippet: "
test = new B().constructor;
})();
"
-frame size: 4
+frame size: 3
parameter count: 1
-bytecode array length: 78
+bytecode array length: 71
bytecodes: [
B(Mov), R(closure), R(1),
B(Mov), R(new_target), R(0),
B(Ldar), R(new_target),
/* 112 E> */ B(StackCheck),
- /* 117 S> */ B(CallRuntime), U16(Runtime::k_GetSuperConstructor), R(1), U8(1),
- B(Star), R(2),
+ /* 117 S> */ B(Ldar), R(1),
+ B(GetSuperConstructor), R(2),
B(Ldar), R(0),
/* 117 E> */ B(New), R(2), R(0), U8(0), U8(2),
B(Star), R(2),
B(Ldar), R(this),
B(JumpIfNotHole), U8(4),
- B(Jump), U8(11),
- B(LdaConstant), U8(0),
- B(Star), R(3),
- /* 117 E> */ B(CallRuntime), U16(Runtime::kThrowReferenceError), R(3), U8(1),
+ B(Jump), U8(7),
+ /* 117 E> */ B(CallRuntime), U16(Runtime::kThrowSuperAlreadyCalledError), R(0), U8(0),
B(Mov), R(2), R(this),
/* 126 S> */ B(Ldar), R(this),
B(JumpIfNotHole), U8(11),
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/ClassDeclarations.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/ClassDeclarations.golden
index 765ce65efd..7b283024c8 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/ClassDeclarations.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/ClassDeclarations.golden
@@ -12,7 +12,7 @@ snippet: "
speak() { console.log(this.name + ' is speaking.'); }
}
"
-frame size: 10
+frame size: 9
parameter count: 1
bytecode array length: 75
bytecodes: [
@@ -21,28 +21,26 @@ bytecodes: [
/* 30 E> */ B(StackCheck),
B(LdaTheHole),
B(Star), R(0),
- /* 34 S> */ B(LdaTheHole),
+ /* 34 S> */ B(CreateClosure), U8(0), U8(2), U8(2),
B(Star), R(3),
- B(CreateClosure), U8(0), U8(2),
+ B(LdaTheHole),
B(Star), R(4),
B(LdaSmi), U8(34),
- B(Star), R(5),
- B(Wide), B(LdaSmi), U16(148),
B(Star), R(6),
- B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(4),
- B(Star), R(3),
- B(LdaNamedProperty), R(3), U8(1), U8(2),
+ B(Wide), B(LdaSmi), U16(148),
+ B(Star), R(7),
+ B(Mov), R(3), R(5),
+ B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4),
B(Star), R(4),
- B(LdaConstant), U8(2),
- B(ToName), R(6),
- B(CreateClosure), U8(3), U8(2),
+ B(LdaConstant), U8(1),
+ B(Star), R(6),
+ B(CreateClosure), U8(2), U8(3), U8(2),
B(Star), R(7),
B(LdaSmi), U8(2),
B(Star), R(8),
- B(LdaZero),
- B(Star), R(9),
- B(Mov), R(4), R(5),
- B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(5), U8(5),
+ B(Ldar), R(7),
+ B(StaDataPropertyInLiteral), R(4), R(6), U8(1), U8(4),
+ B(CallRuntime), U16(Runtime::kInstallClassNameAccessor), R(3), U8(1),
B(CallRuntime), U16(Runtime::kToFastProperties), R(3), U8(1),
B(Star), R(0),
B(Star), R(1),
@@ -52,7 +50,6 @@ bytecodes: [
]
constant pool: [
SHARED_FUNCTION_INFO_TYPE,
- ONE_BYTE_INTERNALIZED_STRING_TYPE ["prototype"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["speak"],
SHARED_FUNCTION_INFO_TYPE,
]
@@ -66,7 +63,7 @@ snippet: "
speak() { console.log(this.name + ' is speaking.'); }
}
"
-frame size: 10
+frame size: 9
parameter count: 1
bytecode array length: 75
bytecodes: [
@@ -75,28 +72,26 @@ bytecodes: [
/* 30 E> */ B(StackCheck),
B(LdaTheHole),
B(Star), R(0),
- /* 34 S> */ B(LdaTheHole),
+ /* 34 S> */ B(CreateClosure), U8(0), U8(2), U8(2),
B(Star), R(3),
- B(CreateClosure), U8(0), U8(2),
+ B(LdaTheHole),
B(Star), R(4),
B(LdaSmi), U8(34),
- B(Star), R(5),
- B(Wide), B(LdaSmi), U16(148),
B(Star), R(6),
- B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(4),
- B(Star), R(3),
- B(LdaNamedProperty), R(3), U8(1), U8(2),
+ B(Wide), B(LdaSmi), U16(148),
+ B(Star), R(7),
+ B(Mov), R(3), R(5),
+ B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4),
B(Star), R(4),
- B(LdaConstant), U8(2),
- B(ToName), R(6),
- B(CreateClosure), U8(3), U8(2),
+ B(LdaConstant), U8(1),
+ B(Star), R(6),
+ B(CreateClosure), U8(2), U8(3), U8(2),
B(Star), R(7),
B(LdaSmi), U8(2),
B(Star), R(8),
- B(LdaZero),
- B(Star), R(9),
- B(Mov), R(4), R(5),
- B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(5), U8(5),
+ B(Ldar), R(7),
+ B(StaDataPropertyInLiteral), R(4), R(6), U8(1), U8(4),
+ B(CallRuntime), U16(Runtime::kInstallClassNameAccessor), R(3), U8(1),
B(CallRuntime), U16(Runtime::kToFastProperties), R(3), U8(1),
B(Star), R(0),
B(Star), R(1),
@@ -106,7 +101,6 @@ bytecodes: [
]
constant pool: [
SHARED_FUNCTION_INFO_TYPE,
- ONE_BYTE_INTERNALIZED_STRING_TYPE ["prototype"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["speak"],
SHARED_FUNCTION_INFO_TYPE,
]
@@ -122,9 +116,9 @@ snippet: "
static [n1]() { return n1; }
}
"
-frame size: 11
+frame size: 10
parameter count: 1
-bytecode array length: 121
+bytecode array length: 117
bytecodes: [
B(CreateFunctionContext), U8(2),
B(PushContext), R(3),
@@ -137,40 +131,36 @@ bytecodes: [
/* 57 E> */ B(StaCurrentContextSlot), U8(5),
B(LdaTheHole),
B(Star), R(0),
- /* 62 S> */ B(LdaTheHole),
+ /* 62 S> */ B(CreateClosure), U8(2), U8(2), U8(2),
B(Star), R(4),
- B(CreateClosure), U8(2), U8(2),
+ B(LdaTheHole),
B(Star), R(5),
B(LdaSmi), U8(62),
- B(Star), R(6),
- B(Wide), B(LdaSmi), U16(128),
B(Star), R(7),
- B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4),
- B(Star), R(4),
- B(LdaNamedProperty), R(4), U8(3), U8(2),
+ B(Wide), B(LdaSmi), U16(128),
+ B(Star), R(8),
+ B(Mov), R(4), R(6),
+ B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(4),
B(Star), R(5),
B(LdaCurrentContextSlot), U8(4),
/* 75 E> */ B(ToName), R(7),
- B(CreateClosure), U8(4), U8(2),
+ B(CreateClosure), U8(3), U8(3), U8(2),
B(Star), R(8),
B(LdaSmi), U8(2),
B(Star), R(9),
- B(LdaSmi), U8(1),
- B(Star), R(10),
- B(Mov), R(5), R(6),
- B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(6), U8(5),
+ B(Ldar), R(8),
+ B(StaDataPropertyInLiteral), R(5), R(7), U8(3), U8(5),
B(LdaCurrentContextSlot), U8(5),
/* 106 E> */ B(ToName), R(7),
- B(LdaConstant), U8(3),
+ B(LdaConstant), U8(4),
B(TestEqualStrict), R(7), U8(0),
B(Mov), R(4), R(6),
B(JumpIfToBooleanFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowStaticPrototypeError), R(0), U8(0),
- B(CreateClosure), U8(5), U8(2),
+ B(CreateClosure), U8(5), U8(4), U8(2),
B(Star), R(8),
- B(LdaSmi), U8(1),
- B(Star), R(10),
- B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(6), U8(5),
+ B(StaDataPropertyInLiteral), R(6), R(7), U8(3), U8(7),
+ B(CallRuntime), U16(Runtime::kInstallClassNameAccessorWithCheck), R(4), U8(1),
B(CallRuntime), U16(Runtime::kToFastProperties), R(4), U8(1),
B(Star), R(0),
B(Star), R(1),
@@ -182,8 +172,8 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["a"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["b"],
SHARED_FUNCTION_INFO_TYPE,
- ONE_BYTE_INTERNALIZED_STRING_TYPE ["prototype"],
SHARED_FUNCTION_INFO_TYPE,
+ ONE_BYTE_INTERNALIZED_STRING_TYPE ["prototype"],
SHARED_FUNCTION_INFO_TYPE,
]
handlers: [
@@ -195,9 +185,9 @@ snippet: "
class C { constructor() { count++; }}
return new C();
"
-frame size: 8
+frame size: 9
parameter count: 1
-bytecode array length: 61
+bytecode array length: 64
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(3),
@@ -208,29 +198,90 @@ bytecodes: [
/* 46 E> */ B(StaCurrentContextSlot), U8(4),
B(LdaTheHole),
B(Star), R(0),
- /* 49 S> */ B(LdaTheHole),
+ /* 49 S> */ B(CreateClosure), U8(0), U8(2), U8(2),
B(Star), R(4),
- B(CreateClosure), U8(0), U8(2),
+ B(LdaTheHole),
B(Star), R(5),
B(LdaSmi), U8(49),
- B(Star), R(6),
- B(LdaSmi), U8(86),
B(Star), R(7),
- B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4),
- B(Star), R(4),
- B(LdaNamedProperty), R(4), U8(1), U8(2),
+ B(LdaSmi), U8(86),
+ B(Star), R(8),
+ B(Mov), R(4), R(6),
+ B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(4),
B(Star), R(5),
+ B(CallRuntime), U16(Runtime::kInstallClassNameAccessor), R(4), U8(1),
B(CallRuntime), U16(Runtime::kToFastProperties), R(4), U8(1),
B(Star), R(0),
B(Star), R(1),
B(Star), R(2),
/* 87 S> */ B(Nop),
- /* 94 E> */ B(New), R(2), R(0), U8(0), U8(4),
+ /* 94 E> */ B(New), R(2), R(0), U8(0), U8(3),
/* 103 S> */ B(Return),
]
constant pool: [
SHARED_FUNCTION_INFO_TYPE,
- ONE_BYTE_INTERNALIZED_STRING_TYPE ["prototype"],
+]
+handlers: [
+]
+
+---
+snippet: "
+ (class {})
+ class E { static name () {}}
+"
+frame size: 10
+parameter count: 1
+bytecode array length: 102
+bytecodes: [
+ B(LdaTheHole),
+ B(Star), R(3),
+ /* 30 E> */ B(StackCheck),
+ /* 35 S> */ B(CreateClosure), U8(0), U8(2), U8(2),
+ B(Star), R(4),
+ B(LdaTheHole),
+ B(Star), R(5),
+ B(LdaSmi), U8(35),
+ B(Star), R(7),
+ B(LdaSmi), U8(43),
+ B(Star), R(8),
+ B(Mov), R(4), R(6),
+ B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(4),
+ B(Star), R(5),
+ B(CallRuntime), U16(Runtime::kToFastProperties), R(4), U8(1),
+ B(Star), R(1),
+ B(LdaTheHole),
+ B(Star), R(0),
+ /* 45 S> */ B(CreateClosure), U8(1), U8(3), U8(2),
+ B(Star), R(4),
+ B(LdaTheHole),
+ B(Star), R(5),
+ B(LdaSmi), U8(45),
+ B(Star), R(7),
+ B(LdaSmi), U8(73),
+ B(Star), R(8),
+ B(Mov), R(4), R(6),
+ B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(4),
+ B(Star), R(5),
+ B(LdaConstant), U8(2),
+ B(Star), R(7),
+ B(CreateClosure), U8(3), U8(4), U8(2),
+ B(Star), R(8),
+ B(LdaSmi), U8(2),
+ B(Star), R(9),
+ B(Ldar), R(8),
+ B(StaDataPropertyInLiteral), R(6), R(7), U8(1), U8(5),
+ B(CallRuntime), U16(Runtime::kToFastProperties), R(4), U8(1),
+ B(Star), R(0),
+ B(Star), R(2),
+ B(Star), R(3),
+ B(LdaUndefined),
+ /* 74 S> */ B(Return),
+]
+constant pool: [
+ SHARED_FUNCTION_INFO_TYPE,
+ SHARED_FUNCTION_INFO_TYPE,
+ ONE_BYTE_INTERNALIZED_STRING_TYPE ["name"],
+ SHARED_FUNCTION_INFO_TYPE,
]
handlers: [
]
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/CompoundExpressions.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/CompoundExpressions.golden
index c5ecec9abf..273f3323eb 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/CompoundExpressions.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/CompoundExpressions.golden
@@ -109,17 +109,17 @@ snippet: "
"
frame size: 2
parameter count: 1
-bytecode array length: 24
+bytecode array length: 25
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(0),
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(1),
/* 42 E> */ B(StaCurrentContextSlot), U8(4),
- /* 45 S> */ B(CreateClosure), U8(0), U8(2),
+ /* 45 S> */ B(CreateClosure), U8(0), U8(2), U8(2),
/* 75 S> */ B(LdaCurrentContextSlot), U8(4),
B(Star), R(1),
- B(BitwiseOrSmi), U8(24), R(1), U8(2),
+ B(BitwiseOrSmi), U8(24), R(1), U8(3),
/* 77 E> */ B(StaCurrentContextSlot), U8(4),
B(LdaUndefined),
/* 84 S> */ B(Return),
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/ConstVariableContextSlot.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/ConstVariableContextSlot.golden
index 8ee13434af..8dc85b3326 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/ConstVariableContextSlot.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/ConstVariableContextSlot.golden
@@ -11,13 +11,13 @@ snippet: "
"
frame size: 2
parameter count: 1
-bytecode array length: 19
+bytecode array length: 20
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(1),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
- B(CreateClosure), U8(0), U8(2),
+ B(CreateClosure), U8(0), U8(2), U8(2),
B(Star), R(0),
/* 30 E> */ B(StackCheck),
/* 44 S> */ B(LdaSmi), U8(10),
@@ -37,13 +37,13 @@ snippet: "
"
frame size: 2
parameter count: 1
-bytecode array length: 20
+bytecode array length: 21
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(1),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
- B(CreateClosure), U8(0), U8(2),
+ B(CreateClosure), U8(0), U8(2), U8(2),
B(Star), R(0),
/* 30 E> */ B(StackCheck),
/* 44 S> */ B(LdaSmi), U8(10),
@@ -63,13 +63,13 @@ snippet: "
"
frame size: 4
parameter count: 1
-bytecode array length: 39
+bytecode array length: 40
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(1),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
- B(CreateClosure), U8(0), U8(2),
+ B(CreateClosure), U8(0), U8(2), U8(2),
B(Star), R(0),
/* 30 E> */ B(StackCheck),
/* 47 S> */ B(LdaSmi), U8(20),
@@ -97,13 +97,13 @@ snippet: "
"
frame size: 2
parameter count: 1
-bytecode array length: 26
+bytecode array length: 27
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(1),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
- B(CreateClosure), U8(0), U8(2),
+ B(CreateClosure), U8(0), U8(2), U8(2),
B(Star), R(0),
/* 30 E> */ B(StackCheck),
/* 44 S> */ B(LdaSmi), U8(10),
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/ContextParameters.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/ContextParameters.golden
index 9a05916e14..63e48fd10a 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/ContextParameters.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/ContextParameters.golden
@@ -13,14 +13,14 @@ snippet: "
"
frame size: 1
parameter count: 2
-bytecode array length: 13
+bytecode array length: 14
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(0),
B(Ldar), R(arg0),
B(StaCurrentContextSlot), U8(4),
/* 10 E> */ B(StackCheck),
- /* 19 S> */ B(CreateClosure), U8(0), U8(2),
+ /* 19 S> */ B(CreateClosure), U8(0), U8(2), U8(2),
/* 52 S> */ B(Return),
]
constant pool: [
@@ -36,14 +36,14 @@ snippet: "
"
frame size: 2
parameter count: 2
-bytecode array length: 17
+bytecode array length: 18
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(1),
B(Ldar), R(arg0),
B(StaCurrentContextSlot), U8(4),
/* 10 E> */ B(StackCheck),
- /* 27 S> */ B(CreateClosure), U8(0), U8(2),
+ /* 27 S> */ B(CreateClosure), U8(0), U8(2), U8(2),
B(Star), R(0),
/* 53 S> */ B(LdaCurrentContextSlot), U8(4),
/* 66 S> */ B(Return),
@@ -61,7 +61,7 @@ snippet: "
"
frame size: 1
parameter count: 5
-bytecode array length: 17
+bytecode array length: 18
bytecodes: [
B(CreateFunctionContext), U8(2),
B(PushContext), R(0),
@@ -70,7 +70,7 @@ bytecodes: [
B(Ldar), R(arg2),
B(StaCurrentContextSlot), U8(4),
/* 10 E> */ B(StackCheck),
- /* 29 S> */ B(CreateClosure), U8(0), U8(2),
+ /* 29 S> */ B(CreateClosure), U8(0), U8(2), U8(2),
/* 61 S> */ B(Return),
]
constant pool: [
@@ -86,14 +86,14 @@ snippet: "
"
frame size: 1
parameter count: 1
-bytecode array length: 13
+bytecode array length: 14
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(0),
/* 10 E> */ B(StackCheck),
/* 26 S> */ B(Ldar), R(this),
/* 26 E> */ B(StaCurrentContextSlot), U8(4),
- /* 32 S> */ B(CreateClosure), U8(0), U8(2),
+ /* 32 S> */ B(CreateClosure), U8(0), U8(2), U8(2),
/* 65 S> */ B(Return),
]
constant pool: [
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/ContextVariables.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/ContextVariables.golden
index f4b7943740..b0df006a63 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/ContextVariables.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/ContextVariables.golden
@@ -11,12 +11,12 @@ snippet: "
"
frame size: 1
parameter count: 1
-bytecode array length: 9
+bytecode array length: 10
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(0),
/* 30 E> */ B(StackCheck),
- /* 41 S> */ B(CreateClosure), U8(0), U8(2),
+ /* 41 S> */ B(CreateClosure), U8(0), U8(2), U8(2),
/* 71 S> */ B(Return),
]
constant pool: [
@@ -31,14 +31,14 @@ snippet: "
"
frame size: 1
parameter count: 1
-bytecode array length: 13
+bytecode array length: 14
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(0),
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(1),
/* 42 E> */ B(StaCurrentContextSlot), U8(4),
- /* 45 S> */ B(CreateClosure), U8(0), U8(2),
+ /* 45 S> */ B(CreateClosure), U8(0), U8(2), U8(2),
/* 75 S> */ B(Return),
]
constant pool: [
@@ -53,7 +53,7 @@ snippet: "
"
frame size: 1
parameter count: 1
-bytecode array length: 17
+bytecode array length: 18
bytecodes: [
B(CreateFunctionContext), U8(2),
B(PushContext), R(0),
@@ -62,7 +62,7 @@ bytecodes: [
/* 42 E> */ B(StaCurrentContextSlot), U8(4),
/* 53 S> */ B(LdaSmi), U8(2),
/* 53 E> */ B(StaCurrentContextSlot), U8(5),
- /* 56 S> */ B(CreateClosure), U8(0), U8(2),
+ /* 56 S> */ B(CreateClosure), U8(0), U8(2), U8(2),
/* 92 S> */ B(Return),
]
constant pool: [
@@ -77,14 +77,14 @@ snippet: "
"
frame size: 3
parameter count: 1
-bytecode array length: 21
+bytecode array length: 22
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(0),
/* 30 E> */ B(StackCheck),
/* 41 S> */ B(LdaUndefined),
B(Star), R(2),
- B(CreateClosure), U8(0), U8(2),
+ B(CreateClosure), U8(0), U8(4), U8(2),
B(Star), R(1),
/* 64 E> */ B(Call), R(1), R(2), U8(1), U8(2),
/* 68 S> */ B(LdaCurrentContextSlot), U8(4),
@@ -104,7 +104,7 @@ snippet: "
"
frame size: 2
parameter count: 1
-bytecode array length: 31
+bytecode array length: 32
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(0),
@@ -120,7 +120,7 @@ bytecodes: [
B(StaCurrentContextSlot), U8(4),
/* 69 S> */ B(LdaSmi), U8(2),
/* 69 E> */ B(StaCurrentContextSlot), U8(4),
- /* 72 S> */ B(CreateClosure), U8(1), U8(2),
+ /* 72 S> */ B(CreateClosure), U8(1), U8(2), U8(2),
B(PopContext), R(0),
/* 104 S> */ B(Return),
]
@@ -390,7 +390,7 @@ snippet: "
"
frame size: 3
parameter count: 1
-bytecode array length: 791
+bytecode array length: 792
bytecodes: [
B(CreateFunctionContext), U8(254),
B(PushContext), R(0),
@@ -903,7 +903,7 @@ bytecodes: [
/* 3435 E> */ B(StaCurrentContextSlot), U8(255),
/* 3438 S> */ B(LdaUndefined),
B(Star), R(2),
- B(LdaGlobal), U8(4),
+ B(LdaGlobal), U8(0), U8(4),
B(Star), R(1),
/* 3438 E> */ B(Call), R(1), R(2), U8(1), U8(2),
/* 3454 S> */ B(LdaSmi), U8(100),
@@ -912,6 +912,7 @@ bytecodes: [
/* 3468 S> */ B(Return),
]
constant pool: [
+ ONE_BYTE_INTERNALIZED_STRING_TYPE ["eval"],
]
handlers: [
]
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/CountOperators.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/CountOperators.golden
index b17f3ecf20..61186cd887 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/CountOperators.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/CountOperators.golden
@@ -201,17 +201,17 @@ snippet: "
"
frame size: 2
parameter count: 1
-bytecode array length: 21
+bytecode array length: 22
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(1),
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(1),
/* 42 E> */ B(StaCurrentContextSlot), U8(4),
- /* 53 S> */ B(CreateClosure), U8(0), U8(2),
+ /* 53 S> */ B(CreateClosure), U8(0), U8(2), U8(2),
B(Star), R(0),
/* 78 S> */ B(LdaCurrentContextSlot), U8(4),
- B(Inc), U8(2),
+ B(Inc), U8(3),
/* 87 E> */ B(StaCurrentContextSlot), U8(4),
/* 90 S> */ B(Return),
]
@@ -227,19 +227,19 @@ snippet: "
"
frame size: 3
parameter count: 1
-bytecode array length: 27
+bytecode array length: 28
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(1),
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(1),
/* 42 E> */ B(StaCurrentContextSlot), U8(4),
- /* 53 S> */ B(CreateClosure), U8(0), U8(2),
+ /* 53 S> */ B(CreateClosure), U8(0), U8(2), U8(2),
B(Star), R(0),
/* 78 S> */ B(LdaCurrentContextSlot), U8(4),
B(ToNumber), R(2),
B(Ldar), R(2),
- B(Dec), U8(2),
+ B(Dec), U8(3),
/* 86 E> */ B(StaCurrentContextSlot), U8(4),
B(Ldar), R(2),
/* 90 S> */ B(Return),
@@ -273,7 +273,7 @@ bytecodes: [
/* 84 S> */ B(Return),
]
constant pool: [
- FIXED_ARRAY_TYPE,
+ CONSTANT_ELEMENTS_PAIR_TYPE,
]
handlers: [
]
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/CreateRestParameter.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/CreateRestParameter.golden
index 851b953309..2abe2d8022 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/CreateRestParameter.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/CreateRestParameter.golden
@@ -95,7 +95,7 @@ bytecodes: [
B(Star), R(3),
B(LdaZero),
/* 59 E> */ B(LdaKeyedProperty), R(2), U8(4),
- B(Add), R(3), U8(6),
+ /* 48 E> */ B(Add), R(3), U8(6),
/* 64 S> */ B(Return),
]
constant pool: [
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/DeclareGlobals.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/DeclareGlobals.golden
index 00fa0180e6..91c3bb99d4 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/DeclareGlobals.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/DeclareGlobals.golden
@@ -104,7 +104,7 @@ snippet: "
"
frame size: 4
parameter count: 1
-bytecode array length: 31
+bytecode array length: 32
bytecodes: [
B(LdaConstant), U8(0),
B(Star), R(1),
@@ -115,14 +115,15 @@ bytecodes: [
/* 0 E> */ B(StackCheck),
/* 16 S> */ B(LdaUndefined),
B(Star), R(2),
- B(LdaGlobal), U8(2),
+ B(LdaGlobal), U8(1), U8(2),
B(Star), R(1),
- /* 16 E> */ B(Call), R(1), R(2), U8(1), U8(4),
+ /* 16 E> */ B(Call), R(1), R(2), U8(1), U8(5),
B(Star), R(0),
/* 20 S> */ B(Return),
]
constant pool: [
FIXED_ARRAY_TYPE,
+ ONE_BYTE_INTERNALIZED_STRING_TYPE ["f"],
]
handlers: [
]
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/Delete.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/Delete.golden
index 12e421e883..e139fd65d1 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/Delete.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/Delete.golden
@@ -98,7 +98,7 @@ snippet: "
"
frame size: 2
parameter count: 1
-bytecode array length: 26
+bytecode array length: 27
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(0),
@@ -106,7 +106,7 @@ bytecodes: [
/* 56 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(1), R(1),
B(Ldar), R(1),
/* 56 E> */ B(StaCurrentContextSlot), U8(4),
- /* 64 S> */ B(CreateClosure), U8(1), U8(2),
+ /* 64 S> */ B(CreateClosure), U8(1), U8(2), U8(2),
/* 93 S> */ B(LdaCurrentContextSlot), U8(4),
B(Star), R(1),
B(LdaSmi), U8(1),
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/ForIn.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/ForIn.golden
index c8cbc7a61d..e03f83d3fc 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/ForIn.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/ForIn.golden
@@ -132,7 +132,7 @@ bytecodes: [
/* 80 S> */ B(Return),
]
constant pool: [
- FIXED_ARRAY_TYPE,
+ CONSTANT_ELEMENTS_PAIR_TYPE,
]
handlers: [
]
@@ -188,7 +188,7 @@ bytecodes: [
]
constant pool: [
FIXED_ARRAY_TYPE,
- FIXED_ARRAY_TYPE,
+ CONSTANT_ELEMENTS_PAIR_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["a"],
]
handlers: [
@@ -233,8 +233,8 @@ bytecodes: [
/* 98 S> */ B(Return),
]
constant pool: [
- FIXED_ARRAY_TYPE,
- FIXED_ARRAY_TYPE,
+ CONSTANT_ELEMENTS_PAIR_TYPE,
+ CONSTANT_ELEMENTS_PAIR_TYPE,
]
handlers: [
]
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/ForOf.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/ForOf.golden
index 96545a94d8..610b8b1a06 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/ForOf.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/ForOf.golden
@@ -11,7 +11,7 @@ snippet: "
"
frame size: 15
parameter count: 1
-bytecode array length: 282
+bytecode array length: 272
bytecodes: [
/* 30 E> */ B(StackCheck),
B(LdaZero),
@@ -19,11 +19,12 @@ bytecodes: [
B(Mov), R(context), R(11),
B(Mov), R(context), R(12),
/* 48 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(9),
- B(Star), R(14),
- B(LdaConstant), U8(1),
- /* 48 E> */ B(LdaKeyedProperty), R(14), U8(4),
B(Star), R(13),
- /* 48 E> */ B(CallProperty), R(13), R(14), U8(1), U8(2),
+ B(LdaNamedProperty), R(13), U8(1), U8(2),
+ B(Star), R(14),
+ B(CallProperty), R(14), R(13), U8(1), U8(4),
+ B(JumpIfJSReceiver), U8(7),
+ B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(2),
/* 45 S> */ B(LdaNamedProperty), R(2), U8(2), U8(8),
B(Star), R(13),
@@ -66,31 +67,28 @@ bytecodes: [
B(Star), R(10),
B(LdaZero),
B(Star), R(9),
- B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
+ B(LdaTheHole),
+ B(SetPendingMessage),
B(Star), R(11),
B(LdaZero),
B(TestEqualStrict), R(4), U8(15),
- B(JumpIfTrue), U8(122),
- B(LdaUndefined),
- B(TestEqualStrict), R(2), U8(16),
- B(JumpIfTrue), U8(116),
- B(LdaNamedProperty), R(2), U8(7), U8(17),
+ B(JumpIfTrue), U8(111),
+ B(LdaNamedProperty), R(2), U8(7), U8(16),
B(Star), R(6),
- B(LdaNull),
- B(TestEqual), R(6), U8(19),
+ B(TestUndetectable), R(6),
B(JumpIfFalse), U8(4),
- B(Jump), U8(102),
+ B(Jump), U8(99),
B(LdaSmi), U8(1),
- B(TestEqualStrict), R(4), U8(20),
- B(JumpIfFalse), U8(70),
+ B(TestEqualStrict), R(4), U8(19),
+ B(JumpIfFalse), U8(67),
B(Ldar), R(6),
B(TypeOf),
B(Star), R(12),
B(LdaConstant), U8(8),
- B(TestEqualStrict), R(12), U8(21),
+ B(TestEqualStrict), R(12), U8(20),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
- B(Wide), B(LdaSmi), U16(130),
+ B(Wide), B(LdaSmi), U16(129),
B(Star), R(12),
B(LdaConstant), U8(9),
B(Star), R(13),
@@ -100,12 +98,13 @@ bytecodes: [
B(Mov), R(6), R(13),
B(Mov), R(2), R(14),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(13), U8(2),
- B(Jump), U8(23),
+ B(Jump), U8(20),
B(Star), R(13),
B(Ldar), R(closure),
B(CreateCatchContext), R(13), U8(5), U8(10),
B(Star), R(12),
- B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
+ B(LdaTheHole),
+ B(SetPendingMessage),
B(Ldar), R(12),
B(PushContext), R(8),
B(PopContext), R(8),
@@ -118,7 +117,8 @@ bytecodes: [
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(7), U8(1),
- B(CallRuntime), U16(Runtime::kInterpreterSetPendingMessage), R(11), U8(1),
+ B(Ldar), R(11),
+ B(SetPendingMessage),
B(LdaZero),
B(TestEqualStrict), R(9), U8(0),
B(JumpIfTrue), U8(4),
@@ -129,7 +129,7 @@ bytecodes: [
/* 62 S> */ B(Return),
]
constant pool: [
- FIXED_ARRAY_TYPE,
+ CONSTANT_ELEMENTS_PAIR_TYPE,
SYMBOL_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
@@ -142,9 +142,9 @@ constant pool: [
FIXED_ARRAY_TYPE,
]
handlers: [
- [7, 120, 126],
- [10, 84, 86],
- [204, 214, 216],
+ [7, 126, 132],
+ [10, 90, 92],
+ [199, 209, 211],
]
---
@@ -154,7 +154,7 @@ snippet: "
"
frame size: 16
parameter count: 1
-bytecode array length: 293
+bytecode array length: 286
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaConstant), U8(0),
@@ -163,10 +163,12 @@ bytecodes: [
B(Star), R(5),
B(Mov), R(context), R(12),
B(Mov), R(context), R(13),
- /* 68 S> */ B(LdaConstant), U8(1),
- /* 68 E> */ B(LdaKeyedProperty), R(0), U8(4),
- B(Star), R(14),
- /* 68 E> */ B(CallProperty), R(14), R(0), U8(1), U8(2),
+ /* 68 S> */ B(LdaNamedProperty), R(0), U8(1), U8(2),
+ B(Star), R(15),
+ B(CallProperty), R(15), R(0), U8(1), U8(4),
+ B(Mov), R(0), R(14),
+ B(JumpIfJSReceiver), U8(7),
+ B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(3),
/* 65 S> */ B(LdaNamedProperty), R(3), U8(2), U8(8),
B(Star), R(14),
@@ -210,31 +212,28 @@ bytecodes: [
B(Star), R(11),
B(LdaSmi), U8(1),
B(Star), R(10),
- B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
+ B(LdaTheHole),
+ B(SetPendingMessage),
B(Star), R(12),
B(LdaZero),
B(TestEqualStrict), R(5), U8(15),
- B(JumpIfTrue), U8(122),
- B(LdaUndefined),
- B(TestEqualStrict), R(3), U8(16),
- B(JumpIfTrue), U8(116),
- B(LdaNamedProperty), R(3), U8(7), U8(17),
+ B(JumpIfTrue), U8(111),
+ B(LdaNamedProperty), R(3), U8(7), U8(16),
B(Star), R(7),
- B(LdaNull),
- B(TestEqual), R(7), U8(19),
+ B(TestUndetectable), R(7),
B(JumpIfFalse), U8(4),
- B(Jump), U8(102),
+ B(Jump), U8(99),
B(LdaSmi), U8(1),
- B(TestEqualStrict), R(5), U8(20),
- B(JumpIfFalse), U8(70),
+ B(TestEqualStrict), R(5), U8(19),
+ B(JumpIfFalse), U8(67),
B(Ldar), R(7),
B(TypeOf),
B(Star), R(13),
B(LdaConstant), U8(8),
- B(TestEqualStrict), R(13), U8(21),
+ B(TestEqualStrict), R(13), U8(20),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
- B(Wide), B(LdaSmi), U16(130),
+ B(Wide), B(LdaSmi), U16(129),
B(Star), R(13),
B(LdaConstant), U8(9),
B(Star), R(14),
@@ -244,12 +243,13 @@ bytecodes: [
B(Mov), R(7), R(14),
B(Mov), R(3), R(15),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(14), U8(2),
- B(Jump), U8(23),
+ B(Jump), U8(20),
B(Star), R(14),
B(Ldar), R(closure),
B(CreateCatchContext), R(14), U8(5), U8(10),
B(Star), R(13),
- B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
+ B(LdaTheHole),
+ B(SetPendingMessage),
B(Ldar), R(13),
B(PushContext), R(9),
B(PopContext), R(9),
@@ -262,7 +262,8 @@ bytecodes: [
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(8), U8(1),
- B(CallRuntime), U16(Runtime::kInterpreterSetPendingMessage), R(12), U8(1),
+ B(Ldar), R(12),
+ B(SetPendingMessage),
B(LdaZero),
B(TestEqualStrict), R(10), U8(0),
B(JumpIfTrue), U8(11),
@@ -291,9 +292,9 @@ constant pool: [
FIXED_ARRAY_TYPE,
]
handlers: [
- [11, 120, 126],
- [14, 84, 86],
- [205, 215, 217],
+ [11, 129, 135],
+ [14, 93, 95],
+ [203, 213, 215],
]
---
@@ -305,7 +306,7 @@ snippet: "
"
frame size: 15
parameter count: 1
-bytecode array length: 300
+bytecode array length: 290
bytecodes: [
/* 30 E> */ B(StackCheck),
B(LdaZero),
@@ -313,11 +314,12 @@ bytecodes: [
B(Mov), R(context), R(11),
B(Mov), R(context), R(12),
/* 48 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(9),
- B(Star), R(14),
- B(LdaConstant), U8(1),
- /* 48 E> */ B(LdaKeyedProperty), R(14), U8(4),
B(Star), R(13),
- /* 48 E> */ B(CallProperty), R(13), R(14), U8(1), U8(2),
+ B(LdaNamedProperty), R(13), U8(1), U8(2),
+ B(Star), R(14),
+ B(CallProperty), R(14), R(13), U8(1), U8(4),
+ B(JumpIfJSReceiver), U8(7),
+ B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(2),
/* 45 S> */ B(LdaNamedProperty), R(2), U8(2), U8(8),
B(Star), R(13),
@@ -368,31 +370,28 @@ bytecodes: [
B(Star), R(10),
B(LdaZero),
B(Star), R(9),
- B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
+ B(LdaTheHole),
+ B(SetPendingMessage),
B(Star), R(11),
B(LdaZero),
B(TestEqualStrict), R(4), U8(17),
- B(JumpIfTrue), U8(122),
- B(LdaUndefined),
- B(TestEqualStrict), R(2), U8(18),
- B(JumpIfTrue), U8(116),
- B(LdaNamedProperty), R(2), U8(7), U8(19),
+ B(JumpIfTrue), U8(111),
+ B(LdaNamedProperty), R(2), U8(7), U8(18),
B(Star), R(6),
- B(LdaNull),
- B(TestEqual), R(6), U8(21),
+ B(TestUndetectable), R(6),
B(JumpIfFalse), U8(4),
- B(Jump), U8(102),
+ B(Jump), U8(99),
B(LdaSmi), U8(1),
- B(TestEqualStrict), R(4), U8(22),
- B(JumpIfFalse), U8(70),
+ B(TestEqualStrict), R(4), U8(21),
+ B(JumpIfFalse), U8(67),
B(Ldar), R(6),
B(TypeOf),
B(Star), R(12),
B(LdaConstant), U8(8),
- B(TestEqualStrict), R(12), U8(23),
+ B(TestEqualStrict), R(12), U8(22),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
- B(Wide), B(LdaSmi), U16(130),
+ B(Wide), B(LdaSmi), U16(129),
B(Star), R(12),
B(LdaConstant), U8(9),
B(Star), R(13),
@@ -402,12 +401,13 @@ bytecodes: [
B(Mov), R(6), R(13),
B(Mov), R(2), R(14),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(13), U8(2),
- B(Jump), U8(23),
+ B(Jump), U8(20),
B(Star), R(13),
B(Ldar), R(closure),
B(CreateCatchContext), R(13), U8(5), U8(10),
B(Star), R(12),
- B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
+ B(LdaTheHole),
+ B(SetPendingMessage),
B(Ldar), R(12),
B(PushContext), R(8),
B(PopContext), R(8),
@@ -420,7 +420,8 @@ bytecodes: [
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(7), U8(1),
- B(CallRuntime), U16(Runtime::kInterpreterSetPendingMessage), R(11), U8(1),
+ B(Ldar), R(11),
+ B(SetPendingMessage),
B(LdaZero),
B(TestEqualStrict), R(9), U8(0),
B(JumpIfTrue), U8(4),
@@ -431,7 +432,7 @@ bytecodes: [
/* 113 S> */ B(Return),
]
constant pool: [
- FIXED_ARRAY_TYPE,
+ CONSTANT_ELEMENTS_PAIR_TYPE,
SYMBOL_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
@@ -444,9 +445,9 @@ constant pool: [
FIXED_ARRAY_TYPE,
]
handlers: [
- [7, 138, 144],
- [10, 102, 104],
- [222, 232, 234],
+ [7, 144, 150],
+ [10, 108, 110],
+ [217, 227, 229],
]
---
@@ -456,7 +457,7 @@ snippet: "
"
frame size: 14
parameter count: 1
-bytecode array length: 307
+bytecode array length: 297
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(1), R(8),
@@ -466,11 +467,12 @@ bytecodes: [
B(Mov), R(context), R(10),
B(Mov), R(context), R(11),
/* 77 S> */ B(CreateArrayLiteral), U8(1), U8(1), U8(9),
- B(Star), R(13),
- B(LdaConstant), U8(2),
- /* 77 E> */ B(LdaKeyedProperty), R(13), U8(4),
B(Star), R(12),
- /* 77 E> */ B(CallProperty), R(12), R(13), U8(1), U8(2),
+ B(LdaNamedProperty), R(12), U8(2), U8(2),
+ B(Star), R(13),
+ B(CallProperty), R(13), R(12), U8(1), U8(4),
+ B(JumpIfJSReceiver), U8(7),
+ B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(1),
/* 74 S> */ B(LdaNamedProperty), R(1), U8(3), U8(8),
B(Star), R(12),
@@ -516,31 +518,28 @@ bytecodes: [
B(Star), R(9),
B(LdaSmi), U8(1),
B(Star), R(8),
- B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
+ B(LdaTheHole),
+ B(SetPendingMessage),
B(Star), R(10),
B(LdaZero),
B(TestEqualStrict), R(3), U8(19),
- B(JumpIfTrue), U8(122),
- B(LdaUndefined),
- B(TestEqualStrict), R(1), U8(20),
- B(JumpIfTrue), U8(116),
- B(LdaNamedProperty), R(1), U8(9), U8(21),
+ B(JumpIfTrue), U8(111),
+ B(LdaNamedProperty), R(1), U8(9), U8(20),
B(Star), R(5),
- B(LdaNull),
- B(TestEqual), R(5), U8(23),
+ B(TestUndetectable), R(5),
B(JumpIfFalse), U8(4),
- B(Jump), U8(102),
+ B(Jump), U8(99),
B(LdaSmi), U8(1),
- B(TestEqualStrict), R(3), U8(24),
- B(JumpIfFalse), U8(70),
+ B(TestEqualStrict), R(3), U8(23),
+ B(JumpIfFalse), U8(67),
B(Ldar), R(5),
B(TypeOf),
B(Star), R(11),
B(LdaConstant), U8(10),
- B(TestEqualStrict), R(11), U8(25),
+ B(TestEqualStrict), R(11), U8(24),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
- B(Wide), B(LdaSmi), U16(130),
+ B(Wide), B(LdaSmi), U16(129),
B(Star), R(11),
B(LdaConstant), U8(11),
B(Star), R(12),
@@ -550,12 +549,13 @@ bytecodes: [
B(Mov), R(5), R(12),
B(Mov), R(1), R(13),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(12), U8(2),
- B(Jump), U8(23),
+ B(Jump), U8(20),
B(Star), R(12),
B(Ldar), R(closure),
B(CreateCatchContext), R(12), U8(7), U8(12),
B(Star), R(11),
- B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
+ B(LdaTheHole),
+ B(SetPendingMessage),
B(Ldar), R(11),
B(PushContext), R(7),
B(PopContext), R(7),
@@ -568,7 +568,8 @@ bytecodes: [
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1),
- B(CallRuntime), U16(Runtime::kInterpreterSetPendingMessage), R(10), U8(1),
+ B(Ldar), R(10),
+ B(SetPendingMessage),
B(LdaZero),
B(TestEqualStrict), R(8), U8(0),
B(JumpIfTrue), U8(11),
@@ -585,7 +586,7 @@ bytecodes: [
]
constant pool: [
FIXED_ARRAY_TYPE,
- FIXED_ARRAY_TYPE,
+ CONSTANT_ELEMENTS_PAIR_TYPE,
SYMBOL_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
@@ -599,8 +600,8 @@ constant pool: [
FIXED_ARRAY_TYPE,
]
handlers: [
- [15, 134, 140],
- [18, 98, 100],
- [219, 229, 231],
+ [15, 140, 146],
+ [18, 104, 106],
+ [214, 224, 226],
]
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/FunctionLiterals.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/FunctionLiterals.golden
index 19aa219ac1..f897381d86 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/FunctionLiterals.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/FunctionLiterals.golden
@@ -11,10 +11,10 @@ snippet: "
"
frame size: 0
parameter count: 1
-bytecode array length: 5
+bytecode array length: 6
bytecodes: [
/* 30 E> */ B(StackCheck),
- /* 34 S> */ B(CreateClosure), U8(0), U8(2),
+ /* 34 S> */ B(CreateClosure), U8(0), U8(2), U8(2),
/* 55 S> */ B(Return),
]
constant pool: [
@@ -29,12 +29,12 @@ snippet: "
"
frame size: 2
parameter count: 1
-bytecode array length: 15
+bytecode array length: 16
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(LdaUndefined),
B(Star), R(1),
- B(CreateClosure), U8(0), U8(2),
+ B(CreateClosure), U8(0), U8(4), U8(2),
B(Star), R(0),
/* 56 E> */ B(Call), R(0), R(1), U8(1), U8(2),
/* 59 S> */ B(Return),
@@ -51,12 +51,12 @@ snippet: "
"
frame size: 3
parameter count: 1
-bytecode array length: 19
+bytecode array length: 20
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(LdaUndefined),
B(Star), R(1),
- B(CreateClosure), U8(0), U8(2),
+ B(CreateClosure), U8(0), U8(4), U8(2),
B(Star), R(0),
B(LdaSmi), U8(1),
B(Star), R(2),
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/GenerateTestUndetectable.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/GenerateTestUndetectable.golden
new file mode 100644
index 0000000000..1ee3738f2e
--- /dev/null
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/GenerateTestUndetectable.golden
@@ -0,0 +1,239 @@
+#
+# Autogenerated by generate-bytecode-expectations.
+#
+
+---
+wrap: yes
+
+---
+snippet: "
+ var obj_a = {val:1};
+ var b = 10;
+ if (obj_a == null) { b = 20;}
+ return b;
+"
+frame size: 3
+parameter count: 1
+bytecode array length: 24
+bytecodes: [
+ /* 30 E> */ B(StackCheck),
+ /* 46 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(1), R(2),
+ B(Mov), R(2), R(0),
+ /* 63 S> */ B(LdaSmi), U8(10),
+ B(Star), R(1),
+ /* 67 S> */ B(TestUndetectable), R(0),
+ B(JumpIfFalse), U8(6),
+ /* 88 S> */ B(LdaSmi), U8(20),
+ B(Star), R(1),
+ /* 97 S> */ B(Ldar), R(1),
+ /* 107 S> */ B(Return),
+]
+constant pool: [
+ FIXED_ARRAY_TYPE,
+]
+handlers: [
+]
+
+---
+snippet: "
+ var obj_a = {val:1};
+ var b = 10;
+ if (obj_a == undefined) { b = 20;}
+ return b;
+"
+frame size: 3
+parameter count: 1
+bytecode array length: 24
+bytecodes: [
+ /* 30 E> */ B(StackCheck),
+ /* 46 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(1), R(2),
+ B(Mov), R(2), R(0),
+ /* 63 S> */ B(LdaSmi), U8(10),
+ B(Star), R(1),
+ /* 67 S> */ B(TestUndetectable), R(0),
+ B(JumpIfFalse), U8(6),
+ /* 93 S> */ B(LdaSmi), U8(20),
+ B(Star), R(1),
+ /* 102 S> */ B(Ldar), R(1),
+ /* 112 S> */ B(Return),
+]
+constant pool: [
+ FIXED_ARRAY_TYPE,
+]
+handlers: [
+]
+
+---
+snippet: "
+ var obj_a = {val:1};
+ var b = 10;
+ if (obj_a != null) { b = 20;}
+ return b;
+"
+frame size: 3
+parameter count: 1
+bytecode array length: 24
+bytecodes: [
+ /* 30 E> */ B(StackCheck),
+ /* 46 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(1), R(2),
+ B(Mov), R(2), R(0),
+ /* 63 S> */ B(LdaSmi), U8(10),
+ B(Star), R(1),
+ /* 67 S> */ B(TestUndetectable), R(0),
+ B(JumpIfTrue), U8(6),
+ /* 88 S> */ B(LdaSmi), U8(20),
+ B(Star), R(1),
+ /* 97 S> */ B(Ldar), R(1),
+ /* 107 S> */ B(Return),
+]
+constant pool: [
+ FIXED_ARRAY_TYPE,
+]
+handlers: [
+]
+
+---
+snippet: "
+ var obj_a = {val:1};
+ var b = 10;
+ if (obj_a != undefined) { b = 20;}
+ return b;
+"
+frame size: 3
+parameter count: 1
+bytecode array length: 24
+bytecodes: [
+ /* 30 E> */ B(StackCheck),
+ /* 46 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(1), R(2),
+ B(Mov), R(2), R(0),
+ /* 63 S> */ B(LdaSmi), U8(10),
+ B(Star), R(1),
+ /* 67 S> */ B(TestUndetectable), R(0),
+ B(JumpIfTrue), U8(6),
+ /* 93 S> */ B(LdaSmi), U8(20),
+ B(Star), R(1),
+ /* 102 S> */ B(Ldar), R(1),
+ /* 112 S> */ B(Return),
+]
+constant pool: [
+ FIXED_ARRAY_TYPE,
+]
+handlers: [
+]
+
+---
+snippet: "
+ var obj_a = {val:1};
+ var b = 10;
+ if (obj_a === null) { b = 20;}
+ return b;
+"
+frame size: 3
+parameter count: 1
+bytecode array length: 24
+bytecodes: [
+ /* 30 E> */ B(StackCheck),
+ /* 46 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(1), R(2),
+ B(Mov), R(2), R(0),
+ /* 63 S> */ B(LdaSmi), U8(10),
+ B(Star), R(1),
+ /* 67 S> */ B(TestNull), R(0),
+ B(JumpIfFalse), U8(6),
+ /* 89 S> */ B(LdaSmi), U8(20),
+ B(Star), R(1),
+ /* 98 S> */ B(Ldar), R(1),
+ /* 108 S> */ B(Return),
+]
+constant pool: [
+ FIXED_ARRAY_TYPE,
+]
+handlers: [
+]
+
+---
+snippet: "
+ var obj_a = {val:1};
+ var b = 10;
+ if (obj_a === undefined) { b = 20;}
+ return b;
+"
+frame size: 3
+parameter count: 1
+bytecode array length: 24
+bytecodes: [
+ /* 30 E> */ B(StackCheck),
+ /* 46 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(1), R(2),
+ B(Mov), R(2), R(0),
+ /* 63 S> */ B(LdaSmi), U8(10),
+ B(Star), R(1),
+ /* 67 S> */ B(TestUndefined), R(0),
+ B(JumpIfFalse), U8(6),
+ /* 94 S> */ B(LdaSmi), U8(20),
+ B(Star), R(1),
+ /* 103 S> */ B(Ldar), R(1),
+ /* 113 S> */ B(Return),
+]
+constant pool: [
+ FIXED_ARRAY_TYPE,
+]
+handlers: [
+]
+
+---
+snippet: "
+ var obj_a = {val:1};
+ var b = 10;
+ if (obj_a !== null) { b = 20;}
+ return b;
+"
+frame size: 3
+parameter count: 1
+bytecode array length: 24
+bytecodes: [
+ /* 30 E> */ B(StackCheck),
+ /* 46 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(1), R(2),
+ B(Mov), R(2), R(0),
+ /* 63 S> */ B(LdaSmi), U8(10),
+ B(Star), R(1),
+ /* 67 S> */ B(TestNull), R(0),
+ B(JumpIfTrue), U8(6),
+ /* 89 S> */ B(LdaSmi), U8(20),
+ B(Star), R(1),
+ /* 98 S> */ B(Ldar), R(1),
+ /* 108 S> */ B(Return),
+]
+constant pool: [
+ FIXED_ARRAY_TYPE,
+]
+handlers: [
+]
+
+---
+snippet: "
+ var obj_a = {val:1};
+ var b = 10;
+ if (obj_a !== undefined) { b = 20;}
+ return b;
+"
+frame size: 3
+parameter count: 1
+bytecode array length: 24
+bytecodes: [
+ /* 30 E> */ B(StackCheck),
+ /* 46 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(1), R(2),
+ B(Mov), R(2), R(0),
+ /* 63 S> */ B(LdaSmi), U8(10),
+ B(Star), R(1),
+ /* 67 S> */ B(TestUndefined), R(0),
+ B(JumpIfTrue), U8(6),
+ /* 94 S> */ B(LdaSmi), U8(20),
+ B(Star), R(1),
+ /* 103 S> */ B(Ldar), R(1),
+ /* 113 S> */ B(Return),
+]
+constant pool: [
+ FIXED_ARRAY_TYPE,
+]
+handlers: [
+]
+
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/Generators.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/Generators.golden
index 7ca3be2345..a53f7f622f 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/Generators.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/Generators.golden
@@ -11,20 +11,22 @@ snippet: "
function* f() { }
f();
"
-frame size: 11
+frame size: 12
parameter count: 1
bytecode array length: 204
bytecodes: [
B(Ldar), R(new_target),
- B(JumpIfUndefined), U8(21),
+ B(JumpIfUndefined), U8(28),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
+ B(PushContext), R(2),
B(ResumeGenerator), R(new_target),
B(Star), R(1),
B(LdaZero),
B(TestEqualStrict), R(1), U8(0),
B(JumpIfTrue), U8(53),
- B(LdaSmi), U8(77),
- B(Star), R(2),
- B(CallRuntime), U16(Runtime::kAbort), R(2), U8(1),
+ B(LdaSmi), U8(78),
+ B(Star), R(3),
+ B(CallRuntime), U16(Runtime::kAbort), R(3), U8(1),
B(LdaSmi), U8(-2),
B(Star), R(1),
B(CreateFunctionContext), U8(2),
@@ -32,78 +34,80 @@ bytecodes: [
B(Ldar), R(this),
B(StaCurrentContextSlot), U8(4),
/* 11 E> */ B(StackCheck),
- B(Mov), R(context), R(4),
+ B(Mov), R(context), R(5),
B(LdaCurrentContextSlot), U8(4),
- B(Star), R(6),
- B(Mov), R(closure), R(5),
- /* 11 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(5), U8(2),
+ B(Star), R(7),
+ B(Mov), R(closure), R(6),
+ /* 11 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(6), U8(2),
B(StaCurrentContextSlot), U8(5),
- B(Star), R(5),
- B(LdaCurrentContextSlot), U8(5),
B(Star), R(6),
+ B(LdaCurrentContextSlot), U8(5),
+ B(Star), R(7),
B(LdaZero),
- B(SuspendGenerator), R(6),
- B(Ldar), R(5),
+ B(SuspendGenerator), R(7),
+ B(Ldar), R(6),
/* 16 S> */ B(Return),
B(LdaSmi), U8(-2),
B(Star), R(1),
- B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(6), U8(1),
- B(Star), R(7),
- B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(6), U8(1),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(7), U8(1),
B(Star), R(8),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(7), U8(1),
+ B(Star), R(9),
B(LdaZero),
- B(TestEqualStrict), R(8), U8(0),
- B(JumpIfTrue), U8(32),
+ B(TestEqualStrict), R(9), U8(0),
+ B(JumpIfTrue), U8(31),
B(LdaSmi), U8(2),
- B(TestEqualStrict), R(8), U8(0),
- B(JumpIfTrue), U8(22),
+ B(TestEqualStrict), R(9), U8(0),
+ B(JumpIfTrue), U8(21),
B(Jump), U8(2),
B(LdaTrue),
- B(Star), R(10),
- B(Mov), R(7), R(9),
- B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(9), U8(2),
- B(Star), R(3),
+ B(Star), R(11),
+ B(Mov), R(8), R(10),
+ B(InvokeIntrinsic), U8(Runtime::k_CreateIterResultObject), R(10), U8(2),
+ B(Star), R(4),
B(LdaZero),
- B(Star), R(2),
- B(Jump), U8(36),
- B(Ldar), R(7),
+ B(Star), R(3),
+ B(Jump), U8(35),
+ B(Ldar), R(8),
/* 11 E> */ B(Throw),
B(LdaUndefined),
- B(Star), R(5),
- B(LdaTrue),
B(Star), R(6),
- B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(5), U8(2),
- B(Star), R(3),
+ B(LdaTrue),
+ B(Star), R(7),
+ B(InvokeIntrinsic), U8(Runtime::k_CreateIterResultObject), R(6), U8(2),
+ B(Star), R(4),
B(LdaSmi), U8(1),
- B(Star), R(2),
+ B(Star), R(3),
B(Jump), U8(14),
B(LdaSmi), U8(-1),
- B(Star), R(2),
- B(Jump), U8(8),
B(Star), R(3),
- B(LdaSmi), U8(2),
- B(Star), R(2),
- B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
+ B(Jump), U8(8),
B(Star), R(4),
- B(LdaCurrentContextSlot), U8(5),
+ B(LdaSmi), U8(2),
+ B(Star), R(3),
+ B(LdaTheHole),
+ B(SetPendingMessage),
B(Star), R(5),
- B(CallRuntime), U16(Runtime::k_GeneratorClose), R(5), U8(1),
- B(CallRuntime), U16(Runtime::kInterpreterSetPendingMessage), R(4), U8(1),
+ B(LdaCurrentContextSlot), U8(5),
+ B(Star), R(6),
+ B(CallRuntime), U16(Runtime::k_GeneratorClose), R(6), U8(1),
+ B(Ldar), R(5),
+ B(SetPendingMessage),
B(LdaZero),
- B(TestEqualStrict), R(2), U8(0),
+ B(TestEqualStrict), R(3), U8(0),
B(JumpIfTrue), U8(18),
B(LdaSmi), U8(1),
- B(TestEqualStrict), R(2), U8(0),
+ B(TestEqualStrict), R(3), U8(0),
B(JumpIfTrue), U8(14),
B(LdaSmi), U8(2),
- B(TestEqualStrict), R(2), U8(0),
+ B(TestEqualStrict), R(3), U8(0),
B(JumpIfTrue), U8(10),
B(Jump), U8(11),
- B(Ldar), R(3),
+ B(Ldar), R(4),
/* 16 S> */ B(Return),
- B(Ldar), R(3),
+ B(Ldar), R(4),
/* 16 S> */ B(Return),
- B(Ldar), R(3),
+ B(Ldar), R(4),
B(ReThrow),
B(LdaUndefined),
/* 16 S> */ B(Return),
@@ -111,7 +115,7 @@ bytecodes: [
constant pool: [
]
handlers: [
- [39, 138, 144],
+ [46, 143, 149],
]
---
@@ -119,12 +123,14 @@ snippet: "
function* f() { yield 42 }
f();
"
-frame size: 11
+frame size: 12
parameter count: 1
-bytecode array length: 301
+bytecode array length: 299
bytecodes: [
B(Ldar), R(new_target),
- B(JumpIfUndefined), U8(28),
+ B(JumpIfUndefined), U8(35),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
+ B(PushContext), R(2),
B(ResumeGenerator), R(new_target),
B(Star), R(1),
B(LdaZero),
@@ -133,9 +139,9 @@ bytecodes: [
B(LdaSmi), U8(1),
B(TestEqualStrict), R(1), U8(0),
B(JumpIfTrueConstant), U8(0),
- B(LdaSmi), U8(77),
- B(Star), R(2),
- B(CallRuntime), U16(Runtime::kAbort), R(2), U8(1),
+ B(LdaSmi), U8(78),
+ B(Star), R(3),
+ B(CallRuntime), U16(Runtime::kAbort), R(3), U8(1),
B(LdaSmi), U8(-2),
B(Star), R(1),
B(CreateFunctionContext), U8(2),
@@ -143,127 +149,129 @@ bytecodes: [
B(Ldar), R(this),
B(StaCurrentContextSlot), U8(4),
/* 11 E> */ B(StackCheck),
- B(Mov), R(context), R(4),
+ B(Mov), R(context), R(5),
B(LdaCurrentContextSlot), U8(4),
- B(Star), R(6),
- B(Mov), R(closure), R(5),
- /* 11 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(5), U8(2),
+ B(Star), R(7),
+ B(Mov), R(closure), R(6),
+ /* 11 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(6), U8(2),
B(StaCurrentContextSlot), U8(5),
- B(Star), R(5),
- B(LdaCurrentContextSlot), U8(5),
B(Star), R(6),
+ B(LdaCurrentContextSlot), U8(5),
+ B(Star), R(7),
B(LdaZero),
- B(SuspendGenerator), R(6),
- B(Ldar), R(5),
+ B(SuspendGenerator), R(7),
+ B(Ldar), R(6),
/* 25 S> */ B(Return),
B(LdaSmi), U8(-2),
B(Star), R(1),
- B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(6), U8(1),
- B(Star), R(7),
- B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(6), U8(1),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(7), U8(1),
B(Star), R(8),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(7), U8(1),
+ B(Star), R(9),
B(LdaZero),
- B(TestEqualStrict), R(8), U8(0),
- B(JumpIfTrue), U8(32),
+ B(TestEqualStrict), R(9), U8(0),
+ B(JumpIfTrue), U8(31),
B(LdaSmi), U8(2),
- B(TestEqualStrict), R(8), U8(0),
- B(JumpIfTrue), U8(22),
+ B(TestEqualStrict), R(9), U8(0),
+ B(JumpIfTrue), U8(21),
B(Jump), U8(2),
B(LdaTrue),
- B(Star), R(10),
- B(Mov), R(7), R(9),
- B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(9), U8(2),
- B(Star), R(3),
+ B(Star), R(11),
+ B(Mov), R(8), R(10),
+ B(InvokeIntrinsic), U8(Runtime::k_CreateIterResultObject), R(10), U8(2),
+ B(Star), R(4),
B(LdaZero),
- B(Star), R(2),
- B(Jump), U8(116),
- B(Ldar), R(7),
+ B(Star), R(3),
+ B(Jump), U8(113),
+ B(Ldar), R(8),
/* 11 E> */ B(Throw),
/* 16 S> */ B(LdaSmi), U8(42),
- B(Star), R(5),
+ B(Star), R(6),
B(LdaFalse),
+ B(Star), R(7),
+ B(InvokeIntrinsic), U8(Runtime::k_CreateIterResultObject), R(6), U8(2),
B(Star), R(6),
- B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(5), U8(2),
- B(Star), R(5),
B(LdaCurrentContextSlot), U8(5),
- B(Star), R(6),
+ B(Star), R(7),
B(LdaSmi), U8(1),
- B(SuspendGenerator), R(6),
- B(Ldar), R(5),
+ B(SuspendGenerator), R(7),
+ B(Ldar), R(6),
/* 25 S> */ B(Return),
B(LdaSmi), U8(-2),
B(Star), R(1),
- B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(6), U8(1),
- B(Star), R(7),
- B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(6), U8(1),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(7), U8(1),
B(Star), R(8),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(7), U8(1),
+ B(Star), R(9),
B(LdaZero),
- B(TestEqualStrict), R(8), U8(0),
- B(JumpIfTrue), U8(33),
+ B(TestEqualStrict), R(9), U8(0),
+ B(JumpIfTrue), U8(32),
B(LdaSmi), U8(2),
- B(TestEqualStrict), R(8), U8(0),
- B(JumpIfTrue), U8(23),
+ B(TestEqualStrict), R(9), U8(0),
+ B(JumpIfTrue), U8(22),
B(Jump), U8(2),
B(LdaTrue),
- B(Star), R(10),
- B(Mov), R(7), R(9),
- B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(9), U8(2),
- B(Star), R(3),
+ B(Star), R(11),
+ B(Mov), R(8), R(10),
+ B(InvokeIntrinsic), U8(Runtime::k_CreateIterResultObject), R(10), U8(2),
+ B(Star), R(4),
B(LdaSmi), U8(1),
- B(Star), R(2),
- B(Jump), U8(36),
- B(Ldar), R(7),
+ B(Star), R(3),
+ B(Jump), U8(35),
+ B(Ldar), R(8),
/* 16 E> */ B(Throw),
B(LdaUndefined),
- B(Star), R(5),
- B(LdaTrue),
B(Star), R(6),
- B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(5), U8(2),
- B(Star), R(3),
+ B(LdaTrue),
+ B(Star), R(7),
+ B(InvokeIntrinsic), U8(Runtime::k_CreateIterResultObject), R(6), U8(2),
+ B(Star), R(4),
B(LdaSmi), U8(2),
- B(Star), R(2),
+ B(Star), R(3),
B(Jump), U8(14),
B(LdaSmi), U8(-1),
- B(Star), R(2),
- B(Jump), U8(8),
B(Star), R(3),
- B(LdaSmi), U8(3),
- B(Star), R(2),
- B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
+ B(Jump), U8(8),
B(Star), R(4),
- B(LdaCurrentContextSlot), U8(5),
+ B(LdaSmi), U8(3),
+ B(Star), R(3),
+ B(LdaTheHole),
+ B(SetPendingMessage),
B(Star), R(5),
- B(CallRuntime), U16(Runtime::k_GeneratorClose), R(5), U8(1),
- B(CallRuntime), U16(Runtime::kInterpreterSetPendingMessage), R(4), U8(1),
+ B(LdaCurrentContextSlot), U8(5),
+ B(Star), R(6),
+ B(CallRuntime), U16(Runtime::k_GeneratorClose), R(6), U8(1),
+ B(Ldar), R(5),
+ B(SetPendingMessage),
B(LdaZero),
- B(TestEqualStrict), R(2), U8(0),
+ B(TestEqualStrict), R(3), U8(0),
B(JumpIfTrue), U8(25),
B(LdaSmi), U8(1),
- B(TestEqualStrict), R(2), U8(0),
+ B(TestEqualStrict), R(3), U8(0),
B(JumpIfTrue), U8(21),
B(LdaSmi), U8(2),
- B(TestEqualStrict), R(2), U8(0),
+ B(TestEqualStrict), R(3), U8(0),
B(JumpIfTrue), U8(17),
B(LdaSmi), U8(3),
- B(TestEqualStrict), R(2), U8(0),
+ B(TestEqualStrict), R(3), U8(0),
B(JumpIfTrue), U8(13),
B(Jump), U8(14),
- B(Ldar), R(3),
+ B(Ldar), R(4),
/* 25 S> */ B(Return),
- B(Ldar), R(3),
+ B(Ldar), R(4),
/* 25 S> */ B(Return),
- B(Ldar), R(3),
+ B(Ldar), R(4),
/* 25 S> */ B(Return),
- B(Ldar), R(3),
+ B(Ldar), R(4),
B(ReThrow),
B(LdaUndefined),
/* 25 S> */ B(Return),
]
constant pool: [
- Smi [132],
+ Smi [130],
]
handlers: [
- [46, 225, 231],
+ [53, 228, 234],
]
---
@@ -271,12 +279,14 @@ snippet: "
function* f() { for (let x of [42]) yield x }
f();
"
-frame size: 17
+frame size: 18
parameter count: 1
-bytecode array length: 796
+bytecode array length: 778
bytecodes: [
B(Ldar), R(new_target),
- B(JumpIfUndefined), U8(28),
+ B(JumpIfUndefined), U8(35),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
+ B(PushContext), R(4),
B(ResumeGenerator), R(new_target),
B(Star), R(3),
B(LdaZero),
@@ -285,9 +295,9 @@ bytecodes: [
B(LdaSmi), U8(1),
B(TestEqualStrict), R(3), U8(0),
B(JumpIfTrueConstant), U8(3),
- B(LdaSmi), U8(77),
- B(Star), R(4),
- B(CallRuntime), U16(Runtime::kAbort), R(4), U8(1),
+ B(LdaSmi), U8(78),
+ B(Star), R(5),
+ B(CallRuntime), U16(Runtime::kAbort), R(5), U8(1),
B(LdaSmi), U8(-2),
B(Star), R(3),
B(CreateFunctionContext), U8(9),
@@ -295,41 +305,41 @@ bytecodes: [
B(Ldar), R(this),
B(StaCurrentContextSlot), U8(4),
/* 11 E> */ B(StackCheck),
- B(Mov), R(context), R(6),
+ B(Mov), R(context), R(7),
B(LdaCurrentContextSlot), U8(4),
- B(Star), R(8),
- B(Mov), R(closure), R(7),
- /* 11 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(7), U8(2),
+ B(Star), R(9),
+ B(Mov), R(closure), R(8),
+ /* 11 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(8), U8(2),
B(StaCurrentContextSlot), U8(5),
- B(Star), R(7),
- B(LdaCurrentContextSlot), U8(5),
B(Star), R(8),
+ B(LdaCurrentContextSlot), U8(5),
+ B(Star), R(9),
B(LdaZero),
- B(SuspendGenerator), R(8),
- B(Ldar), R(7),
+ B(SuspendGenerator), R(9),
+ B(Ldar), R(8),
/* 44 S> */ B(Return),
B(LdaSmi), U8(-2),
B(Star), R(3),
- B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(8), U8(1),
- B(Star), R(9),
- B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(8), U8(1),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(9), U8(1),
B(Star), R(10),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(9), U8(1),
+ B(Star), R(11),
B(LdaZero),
- B(TestEqualStrict), R(10), U8(0),
- B(JumpIfTrue), U8(32),
+ B(TestEqualStrict), R(11), U8(0),
+ B(JumpIfTrue), U8(31),
B(LdaSmi), U8(2),
- B(TestEqualStrict), R(10), U8(0),
- B(JumpIfTrue), U8(22),
+ B(TestEqualStrict), R(11), U8(0),
+ B(JumpIfTrue), U8(21),
B(Jump), U8(2),
B(LdaTrue),
- B(Star), R(12),
- B(Mov), R(9), R(11),
- B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(11), U8(2),
- B(Star), R(5),
+ B(Star), R(13),
+ B(Mov), R(10), R(12),
+ B(InvokeIntrinsic), U8(Runtime::k_CreateIterResultObject), R(12), U8(2),
+ B(Star), R(6),
B(LdaZero),
- B(Star), R(4),
- B(JumpConstant), U8(19),
- B(Ldar), R(9),
+ B(Star), R(5),
+ B(JumpConstant), U8(18),
+ B(Ldar), R(10),
/* 11 E> */ B(Throw),
B(Ldar), R(closure),
B(CreateBlockContext), U8(0),
@@ -338,14 +348,15 @@ bytecodes: [
B(StaCurrentContextSlot), U8(4),
B(LdaZero),
B(StaContextSlot), R(1), U8(9), U8(0),
- B(Mov), R(context), R(9),
B(Mov), R(context), R(10),
+ B(Mov), R(context), R(11),
/* 30 S> */ B(CreateArrayLiteral), U8(1), U8(0), U8(9),
B(Star), R(12),
- B(LdaConstant), U8(2),
- /* 30 E> */ B(LdaKeyedProperty), R(12), U8(4),
- B(Star), R(11),
- /* 30 E> */ B(CallProperty), R(11), R(12), U8(1), U8(2),
+ B(LdaNamedProperty), R(12), U8(2), U8(2),
+ B(Star), R(13),
+ B(CallProperty), R(13), R(12), U8(1), U8(4),
+ B(JumpIfJSReceiver), U8(7),
+ B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
/* 30 E> */ B(StaContextSlot), R(1), U8(7), U8(0),
B(LdaSmi), U8(-2),
B(TestEqual), R(3), U8(0),
@@ -353,29 +364,29 @@ bytecodes: [
B(LdaSmi), U8(1),
B(TestEqualStrict), R(3), U8(0),
B(JumpIfTrueConstant), U8(8),
- B(LdaSmi), U8(77),
- B(Star), R(11),
- B(CallRuntime), U16(Runtime::kAbort), R(11), U8(1),
+ B(LdaSmi), U8(78),
+ B(Star), R(12),
+ B(CallRuntime), U16(Runtime::kAbort), R(12), U8(1),
/* 27 S> */ B(LdaContextSlot), R(1), U8(7), U8(0),
+ B(Star), R(13),
+ B(LdaNamedProperty), R(13), U8(4), U8(8),
B(Star), R(12),
- B(LdaNamedProperty), R(12), U8(4), U8(8),
- B(Star), R(11),
- /* 27 E> */ B(CallProperty), R(11), R(12), U8(1), U8(6),
+ /* 27 E> */ B(CallProperty), R(12), R(13), U8(1), U8(6),
/* 27 E> */ B(StaContextSlot), R(1), U8(8), U8(0),
- B(Star), R(11),
- B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(11), U8(1),
+ B(Star), R(12),
+ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(12), U8(1),
B(ToBooleanLogicalNot),
B(JumpIfFalse), U8(13),
B(LdaContextSlot), R(1), U8(8), U8(0),
- B(Star), R(11),
- B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(11), U8(1),
+ B(Star), R(12),
+ B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(12), U8(1),
B(LdaContextSlot), R(1), U8(8), U8(0),
- B(Star), R(11),
- B(LdaNamedProperty), R(11), U8(5), U8(10),
+ B(Star), R(12),
+ B(LdaNamedProperty), R(12), U8(5), U8(10),
B(JumpIfToBooleanTrueConstant), U8(9),
B(LdaContextSlot), R(1), U8(8), U8(0),
- B(Star), R(11),
- B(LdaNamedProperty), R(11), U8(6), U8(12),
+ B(Star), R(12),
+ B(LdaNamedProperty), R(12), U8(6), U8(12),
B(StaContextSlot), R(1), U8(10), U8(0),
B(LdaSmi), U8(2),
B(StaContextSlot), R(1), U8(9), U8(0),
@@ -390,240 +401,238 @@ bytecodes: [
B(LdaContextSlot), R(1), U8(6), U8(0),
B(StaCurrentContextSlot), U8(4),
/* 36 S> */ B(LdaCurrentContextSlot), U8(4),
- B(Star), R(11),
+ B(Star), R(12),
B(LdaFalse),
+ B(Star), R(13),
+ B(InvokeIntrinsic), U8(Runtime::k_CreateIterResultObject), R(12), U8(2),
B(Star), R(12),
- B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(11), U8(2),
- B(Star), R(11),
B(LdaContextSlot), R(1), U8(5), U8(0),
- B(Star), R(12),
+ B(Star), R(13),
B(LdaSmi), U8(1),
- B(SuspendGenerator), R(12),
- B(Ldar), R(11),
+ B(SuspendGenerator), R(13),
+ B(Ldar), R(12),
/* 44 S> */ B(Return),
B(LdaSmi), U8(-2),
B(Star), R(3),
- B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(12), U8(1),
- B(Star), R(13),
- B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(12), U8(1),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(13), U8(1),
B(Star), R(14),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(13), U8(1),
+ B(Star), R(15),
B(LdaZero),
- B(TestEqualStrict), R(14), U8(0),
- B(JumpIfTrue), U8(44),
+ B(TestEqualStrict), R(15), U8(0),
+ B(JumpIfTrue), U8(43),
B(LdaSmi), U8(2),
- B(TestEqualStrict), R(14), U8(0),
- B(JumpIfTrue), U8(34),
+ B(TestEqualStrict), R(15), U8(0),
+ B(JumpIfTrue), U8(33),
B(Jump), U8(2),
B(LdaTrue),
- B(Star), R(16),
- B(Mov), R(13), R(15),
- B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(15), U8(2),
+ B(Star), R(17),
+ B(Mov), R(14), R(16),
+ B(InvokeIntrinsic), U8(Runtime::k_CreateIterResultObject), R(16), U8(2),
B(PopContext), R(2),
B(PopContext), R(2),
B(PopContext), R(2),
B(PopContext), R(2),
B(PopContext), R(2),
B(PopContext), R(2),
- B(Star), R(8),
+ B(Star), R(9),
B(LdaZero),
- B(Star), R(7),
+ B(Star), R(8),
B(Jump), U8(74),
- B(Ldar), R(13),
+ B(Ldar), R(14),
/* 36 E> */ B(Throw),
B(PopContext), R(2),
B(LdaZero),
B(StaContextSlot), R(1), U8(9), U8(0),
- B(Wide), B(JumpLoop), U16(-221), U16(0),
+ B(Wide), B(JumpLoop), U16(-219), U16(0),
B(Jump), U8(44),
- B(Star), R(11),
+ B(Star), R(12),
B(Ldar), R(closure),
- B(CreateCatchContext), R(11), U8(10), U8(11),
- B(Star), R(10),
+ B(CreateCatchContext), R(12), U8(10), U8(11),
+ B(Star), R(11),
B(PushContext), R(2),
B(LdaContextSlot), R(1), U8(9), U8(0),
- B(Star), R(11),
+ B(Star), R(12),
B(LdaSmi), U8(2),
- B(TestEqualStrict), R(11), U8(14),
+ B(TestEqualStrict), R(12), U8(14),
B(JumpIfFalse), U8(8),
B(LdaSmi), U8(1),
B(StaContextSlot), R(1), U8(9), U8(0),
B(LdaCurrentContextSlot), U8(4),
- B(Star), R(11),
- B(CallRuntime), U16(Runtime::kReThrow), R(11), U8(1),
+ B(Star), R(12),
+ B(CallRuntime), U16(Runtime::kReThrow), R(12), U8(1),
B(PopContext), R(2),
B(LdaSmi), U8(-1),
- B(Star), R(7),
- B(Jump), U8(8),
B(Star), R(8),
- B(LdaSmi), U8(1),
- B(Star), R(7),
- B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
+ B(Jump), U8(8),
B(Star), R(9),
- B(LdaContextSlot), R(1), U8(9), U8(0),
+ B(LdaSmi), U8(1),
+ B(Star), R(8),
+ B(LdaTheHole),
+ B(SetPendingMessage),
B(Star), R(10),
+ B(LdaContextSlot), R(1), U8(9), U8(0),
+ B(Star), R(11),
B(LdaZero),
- B(TestEqualStrict), R(10), U8(15),
+ B(TestEqualStrict), R(11), U8(15),
B(JumpIfTrueConstant), U8(17),
B(LdaContextSlot), R(1), U8(7), U8(0),
- B(Star), R(10),
- B(LdaUndefined),
- B(TestEqualStrict), R(10), U8(16),
- B(JumpIfTrueConstant), U8(18),
- B(LdaContextSlot), R(1), U8(7), U8(0),
- B(Star), R(10),
- B(LdaNamedProperty), R(10), U8(12), U8(17),
+ B(Star), R(11),
+ B(LdaNamedProperty), R(11), U8(12), U8(16),
B(StaContextSlot), R(1), U8(11), U8(0),
B(LdaContextSlot), R(1), U8(11), U8(0),
- B(Star), R(10),
- B(LdaNull),
- B(TestEqual), R(10), U8(19),
+ B(Star), R(11),
+ B(TestUndetectable), R(11),
B(JumpIfFalse), U8(4),
B(JumpConstant), U8(16),
B(LdaContextSlot), R(1), U8(9), U8(0),
- B(Star), R(10),
+ B(Star), R(11),
B(LdaSmi), U8(1),
- B(TestEqualStrict), R(10), U8(20),
- B(JumpIfFalse), U8(78),
+ B(TestEqualStrict), R(11), U8(19),
+ B(JumpIfFalse), U8(75),
B(LdaContextSlot), R(1), U8(11), U8(0),
B(TypeOf),
- B(Star), R(10),
+ B(Star), R(11),
B(LdaConstant), U8(13),
- B(TestEqualStrict), R(10), U8(21),
+ B(TestEqualStrict), R(11), U8(20),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
- B(Wide), B(LdaSmi), U16(130),
- B(Star), R(10),
- B(LdaConstant), U8(14),
+ B(Wide), B(LdaSmi), U16(129),
B(Star), R(11),
- B(CallRuntime), U16(Runtime::kNewTypeError), R(10), U8(2),
+ B(LdaConstant), U8(14),
+ B(Star), R(12),
+ B(CallRuntime), U16(Runtime::kNewTypeError), R(11), U8(2),
B(Throw),
- B(Mov), R(context), R(10),
+ B(Mov), R(context), R(11),
B(LdaContextSlot), R(1), U8(11), U8(0),
- B(Star), R(11),
+ B(Star), R(12),
B(LdaContextSlot), R(1), U8(7), U8(0),
+ B(Star), R(13),
+ B(InvokeIntrinsic), U8(Runtime::k_Call), R(12), U8(2),
+ B(Jump), U8(20),
B(Star), R(12),
- B(InvokeIntrinsic), U8(Runtime::k_Call), R(11), U8(2),
- B(Jump), U8(23),
- B(Star), R(11),
B(Ldar), R(closure),
- B(CreateCatchContext), R(11), U8(10), U8(15),
- B(Star), R(10),
- B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
- B(Ldar), R(10),
+ B(CreateCatchContext), R(12), U8(10), U8(15),
+ B(Star), R(11),
+ B(LdaTheHole),
+ B(SetPendingMessage),
+ B(Ldar), R(11),
B(PushContext), R(2),
B(PopContext), R(2),
B(Jump), U8(47),
B(LdaContextSlot), R(1), U8(11), U8(0),
- B(Star), R(10),
- B(LdaContextSlot), R(1), U8(7), U8(0),
B(Star), R(11),
- B(InvokeIntrinsic), U8(Runtime::k_Call), R(10), U8(2),
+ B(LdaContextSlot), R(1), U8(7), U8(0),
+ B(Star), R(12),
+ B(InvokeIntrinsic), U8(Runtime::k_Call), R(11), U8(2),
B(StaContextSlot), R(1), U8(12), U8(0),
B(LdaContextSlot), R(1), U8(12), U8(0),
- B(Star), R(10),
- B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(10), U8(1),
+ B(Star), R(11),
+ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(11), U8(1),
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(13),
B(LdaContextSlot), R(1), U8(12), U8(0),
- B(Star), R(10),
- B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(10), U8(1),
- B(CallRuntime), U16(Runtime::kInterpreterSetPendingMessage), R(9), U8(1),
+ B(Star), R(11),
+ B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(11), U8(1),
+ B(Ldar), R(10),
+ B(SetPendingMessage),
B(LdaZero),
- B(TestEqualStrict), R(7), U8(0),
+ B(TestEqualStrict), R(8), U8(0),
B(JumpIfTrue), U8(11),
B(LdaSmi), U8(1),
- B(TestEqualStrict), R(7), U8(0),
+ B(TestEqualStrict), R(8), U8(0),
B(JumpIfTrue), U8(17),
B(Jump), U8(28),
B(PopContext), R(1),
B(PopContext), R(1),
B(LdaSmi), U8(1),
- B(Star), R(4),
- B(Mov), R(8), R(5),
- B(Jump), U8(48),
+ B(Star), R(5),
+ B(Mov), R(9), R(6),
+ B(Jump), U8(47),
B(PopContext), R(1),
B(PopContext), R(1),
B(LdaSmi), U8(2),
- B(Star), R(4),
- B(Mov), R(8), R(5),
- B(Jump), U8(35),
+ B(Star), R(5),
+ B(Mov), R(9), R(6),
+ B(Jump), U8(34),
B(PopContext), R(1),
B(LdaUndefined),
- B(Star), R(7),
- B(LdaTrue),
B(Star), R(8),
- B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(7), U8(2),
- B(Star), R(5),
+ B(LdaTrue),
+ B(Star), R(9),
+ B(InvokeIntrinsic), U8(Runtime::k_CreateIterResultObject), R(8), U8(2),
+ B(Star), R(6),
B(LdaSmi), U8(3),
- B(Star), R(4),
+ B(Star), R(5),
B(Jump), U8(14),
B(LdaSmi), U8(-1),
- B(Star), R(4),
- B(Jump), U8(8),
B(Star), R(5),
- B(LdaSmi), U8(4),
- B(Star), R(4),
- B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
+ B(Jump), U8(8),
B(Star), R(6),
- B(LdaCurrentContextSlot), U8(5),
+ B(LdaSmi), U8(4),
+ B(Star), R(5),
+ B(LdaTheHole),
+ B(SetPendingMessage),
B(Star), R(7),
- B(CallRuntime), U16(Runtime::k_GeneratorClose), R(7), U8(1),
- B(CallRuntime), U16(Runtime::kInterpreterSetPendingMessage), R(6), U8(1),
+ B(LdaCurrentContextSlot), U8(5),
+ B(Star), R(8),
+ B(CallRuntime), U16(Runtime::k_GeneratorClose), R(8), U8(1),
+ B(Ldar), R(7),
+ B(SetPendingMessage),
B(LdaZero),
- B(TestEqualStrict), R(4), U8(0),
+ B(TestEqualStrict), R(5), U8(0),
B(JumpIfTrue), U8(32),
B(LdaSmi), U8(1),
- B(TestEqualStrict), R(4), U8(0),
+ B(TestEqualStrict), R(5), U8(0),
B(JumpIfTrue), U8(28),
B(LdaSmi), U8(2),
- B(TestEqualStrict), R(4), U8(0),
+ B(TestEqualStrict), R(5), U8(0),
B(JumpIfTrue), U8(24),
B(LdaSmi), U8(3),
- B(TestEqualStrict), R(4), U8(0),
+ B(TestEqualStrict), R(5), U8(0),
B(JumpIfTrue), U8(20),
B(LdaSmi), U8(4),
- B(TestEqualStrict), R(4), U8(0),
+ B(TestEqualStrict), R(5), U8(0),
B(JumpIfTrue), U8(16),
B(Jump), U8(17),
- B(Ldar), R(5),
+ B(Ldar), R(6),
/* 44 S> */ B(Return),
- B(Ldar), R(5),
+ B(Ldar), R(6),
/* 44 S> */ B(Return),
- B(Ldar), R(5),
+ B(Ldar), R(6),
B(ReThrow),
- B(Ldar), R(5),
+ B(Ldar), R(6),
/* 44 S> */ B(Return),
- B(Ldar), R(5),
+ B(Ldar), R(6),
B(ReThrow),
B(LdaUndefined),
/* 44 S> */ B(Return),
]
constant pool: [
FIXED_ARRAY_TYPE,
- FIXED_ARRAY_TYPE,
+ CONSTANT_ELEMENTS_PAIR_TYPE,
SYMBOL_TYPE,
- Smi [149],
+ Smi [154],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
FIXED_ARRAY_TYPE,
- Smi [135],
- Smi [152],
+ Smi [134],
+ Smi [150],
ONE_BYTE_INTERNALIZED_STRING_TYPE [".catch"],
FIXED_ARRAY_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["function"],
ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
FIXED_ARRAY_TYPE,
- Smi [136],
- Smi [176],
- Smi [164],
- Smi [601],
+ Smi [133],
+ Smi [159],
+ Smi [582],
]
handlers: [
- [46, 710, 716],
- [143, 438, 444],
- [146, 394, 396],
- [557, 573, 575],
+ [53, 697, 703],
+ [149, 448, 454],
+ [152, 404, 406],
+ [550, 566, 568],
]
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/GlobalCompoundExpressions.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/GlobalCompoundExpressions.golden
index f8bece5c39..57403bc402 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/GlobalCompoundExpressions.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/GlobalCompoundExpressions.golden
@@ -14,10 +14,10 @@ snippet: "
"
frame size: 1
parameter count: 1
-bytecode array length: 13
+bytecode array length: 14
bytecodes: [
/* 26 E> */ B(StackCheck),
- /* 31 S> */ B(LdaGlobal), U8(2),
+ /* 31 S> */ B(LdaGlobal), U8(0), U8(2),
B(Star), R(0),
B(BitwiseAndSmi), U8(1), R(0), U8(4),
/* 45 E> */ B(StaGlobalSloppy), U8(0), U8(5),
@@ -37,10 +37,10 @@ snippet: "
"
frame size: 1
parameter count: 1
-bytecode array length: 13
+bytecode array length: 14
bytecodes: [
/* 27 E> */ B(StackCheck),
- /* 32 S> */ B(LdaGlobal), U8(2),
+ /* 32 S> */ B(LdaGlobal), U8(0), U8(2),
B(Star), R(0),
B(AddSmi), U8(1), R(0), U8(4),
/* 51 E> */ B(StaGlobalSloppy), U8(0), U8(5),
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/GlobalCountOperators.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/GlobalCountOperators.golden
index 1e0d530af5..a6090aadf0 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/GlobalCountOperators.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/GlobalCountOperators.golden
@@ -14,10 +14,10 @@ snippet: "
"
frame size: 0
parameter count: 1
-bytecode array length: 9
+bytecode array length: 10
bytecodes: [
/* 26 E> */ B(StackCheck),
- /* 31 S> */ B(LdaGlobal), U8(2),
+ /* 31 S> */ B(LdaGlobal), U8(0), U8(2),
B(Inc), U8(6),
/* 40 E> */ B(StaGlobalSloppy), U8(0), U8(4),
/* 48 S> */ B(Return),
@@ -36,10 +36,10 @@ snippet: "
"
frame size: 1
parameter count: 1
-bytecode array length: 15
+bytecode array length: 16
bytecodes: [
/* 26 E> */ B(StackCheck),
- /* 31 S> */ B(LdaGlobal), U8(2),
+ /* 31 S> */ B(LdaGlobal), U8(0), U8(2),
B(ToNumber), R(0),
B(Ldar), R(0),
B(Dec), U8(6),
@@ -61,10 +61,10 @@ snippet: "
"
frame size: 0
parameter count: 1
-bytecode array length: 9
+bytecode array length: 10
bytecodes: [
/* 27 E> */ B(StackCheck),
- /* 46 S> */ B(LdaGlobal), U8(2),
+ /* 46 S> */ B(LdaGlobal), U8(0), U8(2),
B(Dec), U8(6),
/* 55 E> */ B(StaGlobalStrict), U8(0), U8(4),
/* 68 S> */ B(Return),
@@ -83,10 +83,10 @@ snippet: "
"
frame size: 1
parameter count: 1
-bytecode array length: 15
+bytecode array length: 16
bytecodes: [
/* 27 E> */ B(StackCheck),
- /* 32 S> */ B(LdaGlobal), U8(2),
+ /* 32 S> */ B(LdaGlobal), U8(0), U8(2),
B(ToNumber), R(0),
B(Ldar), R(0),
B(Inc), U8(6),
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/GlobalDelete.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/GlobalDelete.golden
index e9540bb446..b717c71bea 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/GlobalDelete.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/GlobalDelete.golden
@@ -16,16 +16,17 @@ snippet: "
"
frame size: 1
parameter count: 1
-bytecode array length: 10
+bytecode array length: 11
bytecodes: [
/* 32 E> */ B(StackCheck),
- /* 39 S> */ B(LdaGlobal), U8(2),
+ /* 39 S> */ B(LdaGlobal), U8(0), U8(2),
B(Star), R(0),
- B(LdaConstant), U8(0),
+ B(LdaConstant), U8(1),
B(DeletePropertySloppy), R(0),
/* 58 S> */ B(Return),
]
constant pool: [
+ ONE_BYTE_INTERNALIZED_STRING_TYPE ["a"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["x"],
]
handlers: [
@@ -42,16 +43,17 @@ snippet: "
"
frame size: 1
parameter count: 1
-bytecode array length: 10
+bytecode array length: 11
bytecodes: [
/* 28 E> */ B(StackCheck),
- /* 51 S> */ B(LdaGlobal), U8(2),
+ /* 51 S> */ B(LdaGlobal), U8(0), U8(2),
B(Star), R(0),
B(LdaSmi), U8(1),
B(DeletePropertyStrict), R(0),
/* 71 S> */ B(Return),
]
constant pool: [
+ ONE_BYTE_INTERNALIZED_STRING_TYPE ["a"],
]
handlers: [
]
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/LetVariableContextSlot.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/LetVariableContextSlot.golden
index d45386e58b..c1c979c0ac 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/LetVariableContextSlot.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/LetVariableContextSlot.golden
@@ -11,13 +11,13 @@ snippet: "
"
frame size: 2
parameter count: 1
-bytecode array length: 19
+bytecode array length: 20
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(1),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
- B(CreateClosure), U8(0), U8(2),
+ B(CreateClosure), U8(0), U8(2), U8(2),
B(Star), R(0),
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(10),
@@ -37,13 +37,13 @@ snippet: "
"
frame size: 2
parameter count: 1
-bytecode array length: 20
+bytecode array length: 21
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(1),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
- B(CreateClosure), U8(0), U8(2),
+ B(CreateClosure), U8(0), U8(2), U8(2),
B(Star), R(0),
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(10),
@@ -63,13 +63,13 @@ snippet: "
"
frame size: 4
parameter count: 1
-bytecode array length: 38
+bytecode array length: 39
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(1),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
- B(CreateClosure), U8(0), U8(2),
+ B(CreateClosure), U8(0), U8(2), U8(2),
B(Star), R(0),
/* 30 E> */ B(StackCheck),
/* 45 S> */ B(LdaSmi), U8(20),
@@ -98,13 +98,13 @@ snippet: "
"
frame size: 2
parameter count: 1
-bytecode array length: 23
+bytecode array length: 24
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(1),
B(LdaTheHole),
B(StaCurrentContextSlot), U8(4),
- B(CreateClosure), U8(0), U8(2),
+ B(CreateClosure), U8(0), U8(2), U8(2),
B(Star), R(0),
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(10),
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/LoadGlobal.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/LoadGlobal.golden
index 9c1c1b3701..addfa78a98 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/LoadGlobal.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/LoadGlobal.golden
@@ -14,13 +14,14 @@ snippet: "
"
frame size: 0
parameter count: 1
-bytecode array length: 4
+bytecode array length: 5
bytecodes: [
/* 21 E> */ B(StackCheck),
- /* 26 S> */ B(LdaGlobal), U8(2),
+ /* 26 S> */ B(LdaGlobal), U8(0), U8(2),
/* 36 S> */ B(Return),
]
constant pool: [
+ ONE_BYTE_INTERNALIZED_STRING_TYPE ["a"],
]
handlers: [
]
@@ -33,13 +34,14 @@ snippet: "
"
frame size: 0
parameter count: 1
-bytecode array length: 4
+bytecode array length: 5
bytecodes: [
/* 27 E> */ B(StackCheck),
- /* 32 S> */ B(LdaGlobal), U8(2),
+ /* 32 S> */ B(LdaGlobal), U8(0), U8(2),
/* 42 S> */ B(Return),
]
constant pool: [
+ ONE_BYTE_INTERNALIZED_STRING_TYPE ["t"],
]
handlers: [
]
@@ -52,13 +54,14 @@ snippet: "
"
frame size: 0
parameter count: 1
-bytecode array length: 4
+bytecode array length: 5
bytecodes: [
/* 17 E> */ B(StackCheck),
- /* 22 S> */ B(LdaGlobal), U8(2),
+ /* 22 S> */ B(LdaGlobal), U8(0), U8(2),
/* 32 S> */ B(Return),
]
constant pool: [
+ ONE_BYTE_INTERNALIZED_STRING_TYPE ["a"],
]
handlers: [
]
@@ -201,7 +204,7 @@ snippet: "
"
frame size: 0
parameter count: 2
-bytecode array length: 650
+bytecode array length: 652
bytecodes: [
/* 17 E> */ B(StackCheck),
/* 25 S> */ B(Nop),
@@ -460,11 +463,12 @@ bytecodes: [
/* 1286 E> */ B(LdaNamedProperty), R(arg0), U8(0), U8(254),
/* 1295 S> */ B(Nop),
/* 1296 E> */ B(Wide), B(LdaNamedProperty), R16(arg0), U16(0), U16(256),
- /* 1305 S> */ B(Wide), B(LdaGlobal), U16(258),
+ /* 1305 S> */ B(Wide), B(LdaGlobal), U16(1), U16(258),
/* 1315 S> */ B(Return),
]
constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["name"],
+ ONE_BYTE_INTERNALIZED_STRING_TYPE ["a"],
]
handlers: [
]
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/Modules.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/Modules.golden
index 7f13b4a3d5..db5b72c6ee 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/Modules.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/Modules.golden
@@ -11,62 +11,64 @@ top level: yes
snippet: "
import \"bar\";
"
-frame size: 8
+frame size: 9
parameter count: 2
-bytecode array length: 125
+bytecode array length: 131
bytecodes: [
B(Ldar), R(new_target),
- B(JumpIfUndefined), U8(21),
+ B(JumpIfUndefined), U8(28),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
+ B(PushContext), R(2),
B(ResumeGenerator), R(new_target),
B(Star), R(1),
B(LdaZero),
B(TestEqualStrict), R(1), U8(0),
B(JumpIfTrue), U8(63),
- B(LdaSmi), U8(77),
- B(Star), R(2),
- B(CallRuntime), U16(Runtime::kAbort), R(2), U8(1),
+ B(LdaSmi), U8(78),
+ B(Star), R(3),
+ B(CallRuntime), U16(Runtime::kAbort), R(3), U8(1),
B(LdaSmi), U8(-2),
B(Star), R(1),
B(LdaConstant), U8(0),
- B(Star), R(4),
- B(Mov), R(arg0), R(2),
- B(Mov), R(closure), R(3),
- B(CallRuntime), U16(Runtime::kPushModuleContext), R(2), U8(3),
+ B(Star), R(5),
+ B(Mov), R(arg0), R(3),
+ B(Mov), R(closure), R(4),
+ B(CallRuntime), U16(Runtime::kPushModuleContext), R(3), U8(3),
B(PushContext), R(0),
B(Ldar), R(this),
B(StaCurrentContextSlot), U8(4),
/* 0 E> */ B(StackCheck),
B(LdaCurrentContextSlot), U8(4),
- B(Star), R(3),
- B(Mov), R(closure), R(2),
- /* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(2), U8(2),
+ B(Star), R(4),
+ B(Mov), R(closure), R(3),
+ /* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(3), U8(2),
B(StaCurrentContextSlot), U8(5),
- B(Star), R(2),
- B(LdaCurrentContextSlot), U8(5),
B(Star), R(3),
+ B(LdaCurrentContextSlot), U8(5),
+ B(Star), R(4),
B(LdaZero),
- B(SuspendGenerator), R(3),
- B(Ldar), R(2),
+ B(SuspendGenerator), R(4),
+ B(Ldar), R(3),
/* 13 S> */ B(Return),
B(LdaSmi), U8(-2),
B(Star), R(1),
- B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(3), U8(1),
- B(Star), R(4),
- B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(3), U8(1),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(4), U8(1),
B(Star), R(5),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(4), U8(1),
+ B(Star), R(6),
B(LdaZero),
- B(TestEqualStrict), R(5), U8(0),
- B(JumpIfTrue), U8(26),
+ B(TestEqualStrict), R(6), U8(0),
+ B(JumpIfTrue), U8(25),
B(LdaSmi), U8(2),
- B(TestEqualStrict), R(5), U8(0),
- B(JumpIfTrue), U8(16),
+ B(TestEqualStrict), R(6), U8(0),
+ B(JumpIfTrue), U8(15),
B(Jump), U8(2),
B(LdaTrue),
- B(Star), R(7),
- B(Mov), R(4), R(6),
- B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(6), U8(2),
+ B(Star), R(8),
+ B(Mov), R(5), R(7),
+ B(InvokeIntrinsic), U8(Runtime::k_CreateIterResultObject), R(7), U8(2),
/* 13 S> */ B(Return),
- B(Ldar), R(4),
+ B(Ldar), R(5),
/* 0 E> */ B(Throw),
B(LdaUndefined),
/* 13 S> */ B(Return),
@@ -81,62 +83,64 @@ handlers: [
snippet: "
import {foo} from \"bar\";
"
-frame size: 8
+frame size: 9
parameter count: 2
-bytecode array length: 125
+bytecode array length: 131
bytecodes: [
B(Ldar), R(new_target),
- B(JumpIfUndefined), U8(21),
+ B(JumpIfUndefined), U8(28),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
+ B(PushContext), R(2),
B(ResumeGenerator), R(new_target),
B(Star), R(1),
B(LdaZero),
B(TestEqualStrict), R(1), U8(0),
B(JumpIfTrue), U8(63),
- B(LdaSmi), U8(77),
- B(Star), R(2),
- B(CallRuntime), U16(Runtime::kAbort), R(2), U8(1),
+ B(LdaSmi), U8(78),
+ B(Star), R(3),
+ B(CallRuntime), U16(Runtime::kAbort), R(3), U8(1),
B(LdaSmi), U8(-2),
B(Star), R(1),
B(LdaConstant), U8(0),
- B(Star), R(4),
- B(Mov), R(arg0), R(2),
- B(Mov), R(closure), R(3),
- B(CallRuntime), U16(Runtime::kPushModuleContext), R(2), U8(3),
+ B(Star), R(5),
+ B(Mov), R(arg0), R(3),
+ B(Mov), R(closure), R(4),
+ B(CallRuntime), U16(Runtime::kPushModuleContext), R(3), U8(3),
B(PushContext), R(0),
B(Ldar), R(this),
B(StaCurrentContextSlot), U8(4),
/* 0 E> */ B(StackCheck),
B(LdaCurrentContextSlot), U8(4),
- B(Star), R(3),
- B(Mov), R(closure), R(2),
- /* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(2), U8(2),
+ B(Star), R(4),
+ B(Mov), R(closure), R(3),
+ /* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(3), U8(2),
B(StaCurrentContextSlot), U8(5),
- B(Star), R(2),
- B(LdaCurrentContextSlot), U8(5),
B(Star), R(3),
+ B(LdaCurrentContextSlot), U8(5),
+ B(Star), R(4),
B(LdaZero),
- B(SuspendGenerator), R(3),
- B(Ldar), R(2),
+ B(SuspendGenerator), R(4),
+ B(Ldar), R(3),
/* 24 S> */ B(Return),
B(LdaSmi), U8(-2),
B(Star), R(1),
- B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(3), U8(1),
- B(Star), R(4),
- B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(3), U8(1),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(4), U8(1),
B(Star), R(5),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(4), U8(1),
+ B(Star), R(6),
B(LdaZero),
- B(TestEqualStrict), R(5), U8(0),
- B(JumpIfTrue), U8(26),
+ B(TestEqualStrict), R(6), U8(0),
+ B(JumpIfTrue), U8(25),
B(LdaSmi), U8(2),
- B(TestEqualStrict), R(5), U8(0),
- B(JumpIfTrue), U8(16),
+ B(TestEqualStrict), R(6), U8(0),
+ B(JumpIfTrue), U8(15),
B(Jump), U8(2),
B(LdaTrue),
- B(Star), R(7),
- B(Mov), R(4), R(6),
- B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(6), U8(2),
+ B(Star), R(8),
+ B(Mov), R(5), R(7),
+ B(InvokeIntrinsic), U8(Runtime::k_CreateIterResultObject), R(7), U8(2),
/* 24 S> */ B(Return),
- B(Ldar), R(4),
+ B(Ldar), R(5),
/* 0 E> */ B(Throw),
B(LdaUndefined),
/* 24 S> */ B(Return),
@@ -153,74 +157,76 @@ snippet: "
goo(42);
{ let x; { goo(42) } };
"
-frame size: 9
+frame size: 10
parameter count: 2
-bytecode array length: 195
+bytecode array length: 201
bytecodes: [
B(Ldar), R(new_target),
- B(JumpIfUndefined), U8(21),
+ B(JumpIfUndefined), U8(28),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
+ B(PushContext), R(3),
B(ResumeGenerator), R(new_target),
B(Star), R(2),
B(LdaZero),
B(TestEqualStrict), R(2), U8(0),
B(JumpIfTrue), U8(63),
- B(LdaSmi), U8(77),
- B(Star), R(3),
- B(CallRuntime), U16(Runtime::kAbort), R(3), U8(1),
+ B(LdaSmi), U8(78),
+ B(Star), R(4),
+ B(CallRuntime), U16(Runtime::kAbort), R(4), U8(1),
B(LdaSmi), U8(-2),
B(Star), R(2),
B(LdaConstant), U8(0),
- B(Star), R(5),
- B(Mov), R(arg0), R(3),
- B(Mov), R(closure), R(4),
- B(CallRuntime), U16(Runtime::kPushModuleContext), R(3), U8(3),
+ B(Star), R(6),
+ B(Mov), R(arg0), R(4),
+ B(Mov), R(closure), R(5),
+ B(CallRuntime), U16(Runtime::kPushModuleContext), R(4), U8(3),
B(PushContext), R(0),
B(Ldar), R(this),
B(StaCurrentContextSlot), U8(4),
/* 0 E> */ B(StackCheck),
B(LdaCurrentContextSlot), U8(4),
- B(Star), R(4),
- B(Mov), R(closure), R(3),
- /* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(3), U8(2),
+ B(Star), R(5),
+ B(Mov), R(closure), R(4),
+ /* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(4), U8(2),
B(StaCurrentContextSlot), U8(5),
- B(Star), R(3),
- B(LdaCurrentContextSlot), U8(5),
B(Star), R(4),
+ B(LdaCurrentContextSlot), U8(5),
+ B(Star), R(5),
B(LdaZero),
- B(SuspendGenerator), R(4),
- B(Ldar), R(3),
+ B(SuspendGenerator), R(5),
+ B(Ldar), R(4),
/* 64 S> */ B(Return),
B(LdaSmi), U8(-2),
B(Star), R(2),
- B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(4), U8(1),
- B(Star), R(5),
- B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(4), U8(1),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(5), U8(1),
B(Star), R(6),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(5), U8(1),
+ B(Star), R(7),
B(LdaZero),
- B(TestEqualStrict), R(6), U8(0),
- B(JumpIfTrue), U8(26),
+ B(TestEqualStrict), R(7), U8(0),
+ B(JumpIfTrue), U8(25),
B(LdaSmi), U8(2),
- B(TestEqualStrict), R(6), U8(0),
- B(JumpIfTrue), U8(16),
+ B(TestEqualStrict), R(7), U8(0),
+ B(JumpIfTrue), U8(15),
B(Jump), U8(2),
B(LdaTrue),
- B(Star), R(8),
- B(Mov), R(5), R(7),
- B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(7), U8(2),
+ B(Star), R(9),
+ B(Mov), R(6), R(8),
+ B(InvokeIntrinsic), U8(Runtime::k_CreateIterResultObject), R(8), U8(2),
/* 64 S> */ B(Return),
- B(Ldar), R(5),
+ B(Ldar), R(6),
/* 0 E> */ B(Throw),
/* 32 S> */ B(LdaUndefined),
- B(Star), R(4),
+ B(Star), R(5),
/* 32 E> */ B(LdaModuleVariable), U8(-1), U8(0),
B(JumpIfNotHole), U8(11),
B(LdaConstant), U8(1),
- B(Star), R(5),
- B(CallRuntime), U16(Runtime::kThrowReferenceError), R(5), U8(1),
- B(Star), R(3),
+ B(Star), R(6),
+ B(CallRuntime), U16(Runtime::kThrowReferenceError), R(6), U8(1),
+ B(Star), R(4),
B(LdaSmi), U8(42),
- B(Star), R(5),
- /* 32 E> */ B(Call), R(3), R(4), U8(2), U8(2),
+ B(Star), R(6),
+ /* 32 E> */ B(Call), R(4), R(5), U8(2), U8(2),
B(Ldar), R(closure),
B(CreateBlockContext), U8(2),
B(PushContext), R(1),
@@ -229,16 +235,16 @@ bytecodes: [
/* 47 S> */ B(LdaUndefined),
/* 47 E> */ B(StaCurrentContextSlot), U8(4),
/* 52 S> */ B(LdaUndefined),
- B(Star), R(4),
+ B(Star), R(5),
/* 52 E> */ B(LdaModuleVariable), U8(-1), U8(1),
B(JumpIfNotHole), U8(11),
B(LdaConstant), U8(1),
- B(Star), R(5),
- B(CallRuntime), U16(Runtime::kThrowReferenceError), R(5), U8(1),
- B(Star), R(3),
+ B(Star), R(6),
+ B(CallRuntime), U16(Runtime::kThrowReferenceError), R(6), U8(1),
+ B(Star), R(4),
B(LdaSmi), U8(42),
- B(Star), R(5),
- /* 52 E> */ B(Call), R(3), R(4), U8(2), U8(4),
+ B(Star), R(6),
+ /* 52 E> */ B(Call), R(4), R(5), U8(2), U8(4),
B(PopContext), R(1),
B(LdaUndefined),
/* 64 S> */ B(Return),
@@ -257,62 +263,64 @@ snippet: "
foo++;
{ let x; { foo++ } };
"
-frame size: 9
+frame size: 10
parameter count: 2
-bytecode array length: 160
+bytecode array length: 166
bytecodes: [
B(Ldar), R(new_target),
- B(JumpIfUndefined), U8(21),
+ B(JumpIfUndefined), U8(28),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
+ B(PushContext), R(3),
B(ResumeGenerator), R(new_target),
B(Star), R(2),
B(LdaZero),
B(TestEqualStrict), R(2), U8(0),
B(JumpIfTrue), U8(63),
- B(LdaSmi), U8(77),
- B(Star), R(3),
- B(CallRuntime), U16(Runtime::kAbort), R(3), U8(1),
+ B(LdaSmi), U8(78),
+ B(Star), R(4),
+ B(CallRuntime), U16(Runtime::kAbort), R(4), U8(1),
B(LdaSmi), U8(-2),
B(Star), R(2),
B(LdaConstant), U8(0),
- B(Star), R(5),
- B(Mov), R(arg0), R(3),
- B(Mov), R(closure), R(4),
- B(CallRuntime), U16(Runtime::kPushModuleContext), R(3), U8(3),
+ B(Star), R(6),
+ B(Mov), R(arg0), R(4),
+ B(Mov), R(closure), R(5),
+ B(CallRuntime), U16(Runtime::kPushModuleContext), R(4), U8(3),
B(PushContext), R(0),
B(Ldar), R(this),
B(StaCurrentContextSlot), U8(4),
/* 0 E> */ B(StackCheck),
B(LdaCurrentContextSlot), U8(4),
- B(Star), R(4),
- B(Mov), R(closure), R(3),
- /* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(3), U8(2),
+ B(Star), R(5),
+ B(Mov), R(closure), R(4),
+ /* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(4), U8(2),
B(StaCurrentContextSlot), U8(5),
- B(Star), R(3),
- B(LdaCurrentContextSlot), U8(5),
B(Star), R(4),
+ B(LdaCurrentContextSlot), U8(5),
+ B(Star), R(5),
B(LdaZero),
- B(SuspendGenerator), R(4),
- B(Ldar), R(3),
+ B(SuspendGenerator), R(5),
+ B(Ldar), R(4),
/* 49 S> */ B(Return),
B(LdaSmi), U8(-2),
B(Star), R(2),
- B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(4), U8(1),
- B(Star), R(5),
- B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(4), U8(1),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(5), U8(1),
B(Star), R(6),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(5), U8(1),
+ B(Star), R(7),
B(LdaZero),
- B(TestEqualStrict), R(6), U8(0),
- B(JumpIfTrue), U8(26),
+ B(TestEqualStrict), R(7), U8(0),
+ B(JumpIfTrue), U8(25),
B(LdaSmi), U8(2),
- B(TestEqualStrict), R(6), U8(0),
- B(JumpIfTrue), U8(16),
+ B(TestEqualStrict), R(7), U8(0),
+ B(JumpIfTrue), U8(15),
B(Jump), U8(2),
B(LdaTrue),
- B(Star), R(8),
- B(Mov), R(5), R(7),
- B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(7), U8(2),
+ B(Star), R(9),
+ B(Mov), R(6), R(8),
+ B(InvokeIntrinsic), U8(Runtime::k_CreateIterResultObject), R(8), U8(2),
/* 49 S> */ B(Return),
- B(Ldar), R(5),
+ B(Ldar), R(6),
/* 0 E> */ B(Throw),
/* 17 S> */ B(LdaSmi), U8(42),
/* 17 E> */ B(StaModuleVariable), U8(1), U8(0),
@@ -346,27 +354,29 @@ snippet: "
foo++;
{ let x; { foo++ } };
"
-frame size: 9
+frame size: 10
parameter count: 2
-bytecode array length: 164
+bytecode array length: 170
bytecodes: [
B(Ldar), R(new_target),
- B(JumpIfUndefined), U8(21),
+ B(JumpIfUndefined), U8(28),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
+ B(PushContext), R(3),
B(ResumeGenerator), R(new_target),
B(Star), R(2),
B(LdaZero),
B(TestEqualStrict), R(2), U8(0),
B(JumpIfTrue), U8(67),
- B(LdaSmi), U8(77),
- B(Star), R(3),
- B(CallRuntime), U16(Runtime::kAbort), R(3), U8(1),
+ B(LdaSmi), U8(78),
+ B(Star), R(4),
+ B(CallRuntime), U16(Runtime::kAbort), R(4), U8(1),
B(LdaSmi), U8(-2),
B(Star), R(2),
B(LdaConstant), U8(0),
- B(Star), R(5),
- B(Mov), R(arg0), R(3),
- B(Mov), R(closure), R(4),
- B(CallRuntime), U16(Runtime::kPushModuleContext), R(3), U8(3),
+ B(Star), R(6),
+ B(Mov), R(arg0), R(4),
+ B(Mov), R(closure), R(5),
+ B(CallRuntime), U16(Runtime::kPushModuleContext), R(4), U8(3),
B(PushContext), R(0),
B(Ldar), R(this),
B(StaCurrentContextSlot), U8(4),
@@ -374,36 +384,36 @@ bytecodes: [
B(StaModuleVariable), U8(1), U8(0),
/* 0 E> */ B(StackCheck),
B(LdaCurrentContextSlot), U8(4),
- B(Star), R(4),
- B(Mov), R(closure), R(3),
- /* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(3), U8(2),
+ B(Star), R(5),
+ B(Mov), R(closure), R(4),
+ /* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(4), U8(2),
B(StaCurrentContextSlot), U8(5),
- B(Star), R(3),
- B(LdaCurrentContextSlot), U8(5),
B(Star), R(4),
+ B(LdaCurrentContextSlot), U8(5),
+ B(Star), R(5),
B(LdaZero),
- B(SuspendGenerator), R(4),
- B(Ldar), R(3),
+ B(SuspendGenerator), R(5),
+ B(Ldar), R(4),
/* 49 S> */ B(Return),
B(LdaSmi), U8(-2),
B(Star), R(2),
- B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(4), U8(1),
- B(Star), R(5),
- B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(4), U8(1),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(5), U8(1),
B(Star), R(6),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(5), U8(1),
+ B(Star), R(7),
B(LdaZero),
- B(TestEqualStrict), R(6), U8(0),
- B(JumpIfTrue), U8(26),
+ B(TestEqualStrict), R(7), U8(0),
+ B(JumpIfTrue), U8(25),
B(LdaSmi), U8(2),
- B(TestEqualStrict), R(6), U8(0),
- B(JumpIfTrue), U8(16),
+ B(TestEqualStrict), R(7), U8(0),
+ B(JumpIfTrue), U8(15),
B(Jump), U8(2),
B(LdaTrue),
- B(Star), R(8),
- B(Mov), R(5), R(7),
- B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(7), U8(2),
+ B(Star), R(9),
+ B(Mov), R(6), R(8),
+ B(InvokeIntrinsic), U8(Runtime::k_CreateIterResultObject), R(8), U8(2),
/* 49 S> */ B(Return),
- B(Ldar), R(5),
+ B(Ldar), R(6),
/* 0 E> */ B(Throw),
/* 17 S> */ B(LdaSmi), U8(42),
/* 17 E> */ B(StaModuleVariable), U8(1), U8(0),
@@ -437,27 +447,29 @@ snippet: "
foo++;
{ let x; { foo++ } };
"
-frame size: 9
+frame size: 10
parameter count: 2
-bytecode array length: 168
+bytecode array length: 174
bytecodes: [
B(Ldar), R(new_target),
- B(JumpIfUndefined), U8(21),
+ B(JumpIfUndefined), U8(28),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
+ B(PushContext), R(3),
B(ResumeGenerator), R(new_target),
B(Star), R(2),
B(LdaZero),
B(TestEqualStrict), R(2), U8(0),
B(JumpIfTrue), U8(67),
- B(LdaSmi), U8(77),
- B(Star), R(3),
- B(CallRuntime), U16(Runtime::kAbort), R(3), U8(1),
+ B(LdaSmi), U8(78),
+ B(Star), R(4),
+ B(CallRuntime), U16(Runtime::kAbort), R(4), U8(1),
B(LdaSmi), U8(-2),
B(Star), R(2),
B(LdaConstant), U8(0),
- B(Star), R(5),
- B(Mov), R(arg0), R(3),
- B(Mov), R(closure), R(4),
- B(CallRuntime), U16(Runtime::kPushModuleContext), R(3), U8(3),
+ B(Star), R(6),
+ B(Mov), R(arg0), R(4),
+ B(Mov), R(closure), R(5),
+ B(CallRuntime), U16(Runtime::kPushModuleContext), R(4), U8(3),
B(PushContext), R(0),
B(Ldar), R(this),
B(StaCurrentContextSlot), U8(4),
@@ -465,36 +477,36 @@ bytecodes: [
B(StaModuleVariable), U8(1), U8(0),
/* 0 E> */ B(StackCheck),
B(LdaCurrentContextSlot), U8(4),
- B(Star), R(4),
- B(Mov), R(closure), R(3),
- /* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(3), U8(2),
+ B(Star), R(5),
+ B(Mov), R(closure), R(4),
+ /* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(4), U8(2),
B(StaCurrentContextSlot), U8(5),
- B(Star), R(3),
- B(LdaCurrentContextSlot), U8(5),
B(Star), R(4),
+ B(LdaCurrentContextSlot), U8(5),
+ B(Star), R(5),
B(LdaZero),
- B(SuspendGenerator), R(4),
- B(Ldar), R(3),
+ B(SuspendGenerator), R(5),
+ B(Ldar), R(4),
/* 51 S> */ B(Return),
B(LdaSmi), U8(-2),
B(Star), R(2),
- B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(4), U8(1),
- B(Star), R(5),
- B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(4), U8(1),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(5), U8(1),
B(Star), R(6),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(5), U8(1),
+ B(Star), R(7),
B(LdaZero),
- B(TestEqualStrict), R(6), U8(0),
- B(JumpIfTrue), U8(26),
+ B(TestEqualStrict), R(7), U8(0),
+ B(JumpIfTrue), U8(25),
B(LdaSmi), U8(2),
- B(TestEqualStrict), R(6), U8(0),
- B(JumpIfTrue), U8(16),
+ B(TestEqualStrict), R(7), U8(0),
+ B(JumpIfTrue), U8(15),
B(Jump), U8(2),
B(LdaTrue),
- B(Star), R(8),
- B(Mov), R(5), R(7),
- B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(7), U8(2),
+ B(Star), R(9),
+ B(Mov), R(6), R(8),
+ B(InvokeIntrinsic), U8(Runtime::k_CreateIterResultObject), R(8), U8(2),
/* 51 S> */ B(Return),
- B(Ldar), R(5),
+ B(Ldar), R(6),
/* 0 E> */ B(Throw),
/* 19 S> */ B(LdaSmi), U8(42),
/* 19 E> */ B(StaModuleVariable), U8(1), U8(0),
@@ -526,27 +538,29 @@ handlers: [
snippet: "
export default (function () {});
"
-frame size: 8
+frame size: 9
parameter count: 2
-bytecode array length: 135
+bytecode array length: 142
bytecodes: [
B(Ldar), R(new_target),
- B(JumpIfUndefined), U8(21),
+ B(JumpIfUndefined), U8(28),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
+ B(PushContext), R(2),
B(ResumeGenerator), R(new_target),
B(Star), R(1),
B(LdaZero),
B(TestEqualStrict), R(1), U8(0),
B(JumpIfTrue), U8(67),
- B(LdaSmi), U8(77),
- B(Star), R(2),
- B(CallRuntime), U16(Runtime::kAbort), R(2), U8(1),
+ B(LdaSmi), U8(78),
+ B(Star), R(3),
+ B(CallRuntime), U16(Runtime::kAbort), R(3), U8(1),
B(LdaSmi), U8(-2),
B(Star), R(1),
B(LdaConstant), U8(0),
- B(Star), R(4),
- B(Mov), R(arg0), R(2),
- B(Mov), R(closure), R(3),
- B(CallRuntime), U16(Runtime::kPushModuleContext), R(2), U8(3),
+ B(Star), R(5),
+ B(Mov), R(arg0), R(3),
+ B(Mov), R(closure), R(4),
+ B(CallRuntime), U16(Runtime::kPushModuleContext), R(3), U8(3),
B(PushContext), R(0),
B(Ldar), R(this),
B(StaCurrentContextSlot), U8(4),
@@ -554,38 +568,38 @@ bytecodes: [
B(StaModuleVariable), U8(1), U8(0),
/* 0 E> */ B(StackCheck),
B(LdaCurrentContextSlot), U8(4),
- B(Star), R(3),
- B(Mov), R(closure), R(2),
- /* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(2), U8(2),
+ B(Star), R(4),
+ B(Mov), R(closure), R(3),
+ /* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(3), U8(2),
B(StaCurrentContextSlot), U8(5),
- B(Star), R(2),
- B(LdaCurrentContextSlot), U8(5),
B(Star), R(3),
+ B(LdaCurrentContextSlot), U8(5),
+ B(Star), R(4),
B(LdaZero),
- B(SuspendGenerator), R(3),
- B(Ldar), R(2),
+ B(SuspendGenerator), R(4),
+ B(Ldar), R(3),
/* 32 S> */ B(Return),
B(LdaSmi), U8(-2),
B(Star), R(1),
- B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(3), U8(1),
- B(Star), R(4),
- B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(3), U8(1),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(4), U8(1),
B(Star), R(5),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(4), U8(1),
+ B(Star), R(6),
B(LdaZero),
- B(TestEqualStrict), R(5), U8(0),
- B(JumpIfTrue), U8(26),
+ B(TestEqualStrict), R(6), U8(0),
+ B(JumpIfTrue), U8(25),
B(LdaSmi), U8(2),
- B(TestEqualStrict), R(5), U8(0),
- B(JumpIfTrue), U8(16),
+ B(TestEqualStrict), R(6), U8(0),
+ B(JumpIfTrue), U8(15),
B(Jump), U8(2),
B(LdaTrue),
- B(Star), R(7),
- B(Mov), R(4), R(6),
- B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(6), U8(2),
+ B(Star), R(8),
+ B(Mov), R(5), R(7),
+ B(InvokeIntrinsic), U8(Runtime::k_CreateIterResultObject), R(7), U8(2),
/* 32 S> */ B(Return),
- B(Ldar), R(4),
+ B(Ldar), R(5),
/* 0 E> */ B(Throw),
- B(CreateClosure), U8(1), U8(0),
+ B(CreateClosure), U8(1), U8(2), U8(0),
B(StaModuleVariable), U8(1), U8(0),
B(LdaUndefined),
/* 32 S> */ B(Return),
@@ -601,27 +615,29 @@ handlers: [
snippet: "
export default (class {});
"
-frame size: 8
+frame size: 9
parameter count: 2
-bytecode array length: 170
+bytecode array length: 179
bytecodes: [
B(Ldar), R(new_target),
- B(JumpIfUndefined), U8(21),
+ B(JumpIfUndefined), U8(28),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
+ B(PushContext), R(2),
B(ResumeGenerator), R(new_target),
B(Star), R(1),
B(LdaZero),
B(TestEqualStrict), R(1), U8(0),
B(JumpIfTrue), U8(67),
- B(LdaSmi), U8(77),
- B(Star), R(2),
- B(CallRuntime), U16(Runtime::kAbort), R(2), U8(1),
+ B(LdaSmi), U8(78),
+ B(Star), R(3),
+ B(CallRuntime), U16(Runtime::kAbort), R(3), U8(1),
B(LdaSmi), U8(-2),
B(Star), R(1),
B(LdaConstant), U8(0),
- B(Star), R(4),
- B(Mov), R(arg0), R(2),
- B(Mov), R(closure), R(3),
- B(CallRuntime), U16(Runtime::kPushModuleContext), R(2), U8(3),
+ B(Star), R(5),
+ B(Mov), R(arg0), R(3),
+ B(Mov), R(closure), R(4),
+ B(CallRuntime), U16(Runtime::kPushModuleContext), R(3), U8(3),
B(PushContext), R(0),
B(Ldar), R(this),
B(StaCurrentContextSlot), U8(4),
@@ -629,50 +645,50 @@ bytecodes: [
B(StaModuleVariable), U8(1), U8(0),
/* 0 E> */ B(StackCheck),
B(LdaCurrentContextSlot), U8(4),
- B(Star), R(3),
- B(Mov), R(closure), R(2),
- /* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(2), U8(2),
+ B(Star), R(4),
+ B(Mov), R(closure), R(3),
+ /* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(3), U8(2),
B(StaCurrentContextSlot), U8(5),
- B(Star), R(2),
- B(LdaCurrentContextSlot), U8(5),
B(Star), R(3),
+ B(LdaCurrentContextSlot), U8(5),
+ B(Star), R(4),
B(LdaZero),
- B(SuspendGenerator), R(3),
- B(Ldar), R(2),
+ B(SuspendGenerator), R(4),
+ B(Ldar), R(3),
/* 26 S> */ B(Return),
B(LdaSmi), U8(-2),
B(Star), R(1),
- B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(3), U8(1),
- B(Star), R(4),
- B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(3), U8(1),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(4), U8(1),
B(Star), R(5),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(4), U8(1),
+ B(Star), R(6),
B(LdaZero),
- B(TestEqualStrict), R(5), U8(0),
- B(JumpIfTrue), U8(26),
+ B(TestEqualStrict), R(6), U8(0),
+ B(JumpIfTrue), U8(25),
B(LdaSmi), U8(2),
- B(TestEqualStrict), R(5), U8(0),
- B(JumpIfTrue), U8(16),
+ B(TestEqualStrict), R(6), U8(0),
+ B(JumpIfTrue), U8(15),
B(Jump), U8(2),
B(LdaTrue),
- B(Star), R(7),
- B(Mov), R(4), R(6),
- B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(6), U8(2),
+ B(Star), R(8),
+ B(Mov), R(5), R(7),
+ B(InvokeIntrinsic), U8(Runtime::k_CreateIterResultObject), R(7), U8(2),
/* 26 S> */ B(Return),
- B(Ldar), R(4),
+ B(Ldar), R(5),
/* 0 E> */ B(Throw),
- /* 16 S> */ B(LdaTheHole),
- B(Star), R(2),
- B(CreateClosure), U8(1), U8(0),
+ /* 16 S> */ B(CreateClosure), U8(1), U8(2), U8(0),
B(Star), R(3),
- B(LdaSmi), U8(16),
+ B(LdaTheHole),
B(Star), R(4),
+ B(LdaSmi), U8(16),
+ B(Star), R(6),
B(LdaSmi), U8(24),
- B(Star), R(5),
- B(CallRuntime), U16(Runtime::kDefineClass), R(2), U8(4),
- B(Star), R(2),
- B(LdaNamedProperty), R(2), U8(2), U8(2),
- B(Star), R(3),
- B(CallRuntime), U16(Runtime::kToFastProperties), R(2), U8(1),
+ B(Star), R(7),
+ B(Mov), R(3), R(5),
+ B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4),
+ B(Star), R(4),
+ B(CallRuntime), U16(Runtime::kInstallClassNameAccessor), R(3), U8(1),
+ B(CallRuntime), U16(Runtime::kToFastProperties), R(3), U8(1),
B(StaCurrentContextSlot), U8(6),
B(LdaCurrentContextSlot), U8(6),
/* 16 E> */ B(StaModuleVariable), U8(1), U8(0),
@@ -682,7 +698,6 @@ bytecodes: [
constant pool: [
FIXED_ARRAY_TYPE,
SHARED_FUNCTION_INFO_TYPE,
- ONE_BYTE_INTERNALIZED_STRING_TYPE ["prototype"],
]
handlers: [
]
@@ -691,62 +706,64 @@ handlers: [
snippet: "
export {foo as goo} from \"bar\"
"
-frame size: 8
+frame size: 9
parameter count: 2
-bytecode array length: 125
+bytecode array length: 131
bytecodes: [
B(Ldar), R(new_target),
- B(JumpIfUndefined), U8(21),
+ B(JumpIfUndefined), U8(28),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
+ B(PushContext), R(2),
B(ResumeGenerator), R(new_target),
B(Star), R(1),
B(LdaZero),
B(TestEqualStrict), R(1), U8(0),
B(JumpIfTrue), U8(63),
- B(LdaSmi), U8(77),
- B(Star), R(2),
- B(CallRuntime), U16(Runtime::kAbort), R(2), U8(1),
+ B(LdaSmi), U8(78),
+ B(Star), R(3),
+ B(CallRuntime), U16(Runtime::kAbort), R(3), U8(1),
B(LdaSmi), U8(-2),
B(Star), R(1),
B(LdaConstant), U8(0),
- B(Star), R(4),
- B(Mov), R(arg0), R(2),
- B(Mov), R(closure), R(3),
- B(CallRuntime), U16(Runtime::kPushModuleContext), R(2), U8(3),
+ B(Star), R(5),
+ B(Mov), R(arg0), R(3),
+ B(Mov), R(closure), R(4),
+ B(CallRuntime), U16(Runtime::kPushModuleContext), R(3), U8(3),
B(PushContext), R(0),
B(Ldar), R(this),
B(StaCurrentContextSlot), U8(4),
/* 0 E> */ B(StackCheck),
B(LdaCurrentContextSlot), U8(4),
- B(Star), R(3),
- B(Mov), R(closure), R(2),
- /* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(2), U8(2),
+ B(Star), R(4),
+ B(Mov), R(closure), R(3),
+ /* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(3), U8(2),
B(StaCurrentContextSlot), U8(5),
- B(Star), R(2),
- B(LdaCurrentContextSlot), U8(5),
B(Star), R(3),
+ B(LdaCurrentContextSlot), U8(5),
+ B(Star), R(4),
B(LdaZero),
- B(SuspendGenerator), R(3),
- B(Ldar), R(2),
+ B(SuspendGenerator), R(4),
+ B(Ldar), R(3),
/* 30 S> */ B(Return),
B(LdaSmi), U8(-2),
B(Star), R(1),
- B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(3), U8(1),
- B(Star), R(4),
- B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(3), U8(1),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(4), U8(1),
B(Star), R(5),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(4), U8(1),
+ B(Star), R(6),
B(LdaZero),
- B(TestEqualStrict), R(5), U8(0),
- B(JumpIfTrue), U8(26),
+ B(TestEqualStrict), R(6), U8(0),
+ B(JumpIfTrue), U8(25),
B(LdaSmi), U8(2),
- B(TestEqualStrict), R(5), U8(0),
- B(JumpIfTrue), U8(16),
+ B(TestEqualStrict), R(6), U8(0),
+ B(JumpIfTrue), U8(15),
B(Jump), U8(2),
B(LdaTrue),
- B(Star), R(7),
- B(Mov), R(4), R(6),
- B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(6), U8(2),
+ B(Star), R(8),
+ B(Mov), R(5), R(7),
+ B(InvokeIntrinsic), U8(Runtime::k_CreateIterResultObject), R(7), U8(2),
/* 30 S> */ B(Return),
- B(Ldar), R(4),
+ B(Ldar), R(5),
/* 0 E> */ B(Throw),
B(LdaUndefined),
/* 30 S> */ B(Return),
@@ -761,62 +778,64 @@ handlers: [
snippet: "
export * from \"bar\"
"
-frame size: 8
+frame size: 9
parameter count: 2
-bytecode array length: 125
+bytecode array length: 131
bytecodes: [
B(Ldar), R(new_target),
- B(JumpIfUndefined), U8(21),
+ B(JumpIfUndefined), U8(28),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
+ B(PushContext), R(2),
B(ResumeGenerator), R(new_target),
B(Star), R(1),
B(LdaZero),
B(TestEqualStrict), R(1), U8(0),
B(JumpIfTrue), U8(63),
- B(LdaSmi), U8(77),
- B(Star), R(2),
- B(CallRuntime), U16(Runtime::kAbort), R(2), U8(1),
+ B(LdaSmi), U8(78),
+ B(Star), R(3),
+ B(CallRuntime), U16(Runtime::kAbort), R(3), U8(1),
B(LdaSmi), U8(-2),
B(Star), R(1),
B(LdaConstant), U8(0),
- B(Star), R(4),
- B(Mov), R(arg0), R(2),
- B(Mov), R(closure), R(3),
- B(CallRuntime), U16(Runtime::kPushModuleContext), R(2), U8(3),
+ B(Star), R(5),
+ B(Mov), R(arg0), R(3),
+ B(Mov), R(closure), R(4),
+ B(CallRuntime), U16(Runtime::kPushModuleContext), R(3), U8(3),
B(PushContext), R(0),
B(Ldar), R(this),
B(StaCurrentContextSlot), U8(4),
/* 0 E> */ B(StackCheck),
B(LdaCurrentContextSlot), U8(4),
- B(Star), R(3),
- B(Mov), R(closure), R(2),
- /* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(2), U8(2),
+ B(Star), R(4),
+ B(Mov), R(closure), R(3),
+ /* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(3), U8(2),
B(StaCurrentContextSlot), U8(5),
- B(Star), R(2),
- B(LdaCurrentContextSlot), U8(5),
B(Star), R(3),
+ B(LdaCurrentContextSlot), U8(5),
+ B(Star), R(4),
B(LdaZero),
- B(SuspendGenerator), R(3),
- B(Ldar), R(2),
+ B(SuspendGenerator), R(4),
+ B(Ldar), R(3),
/* 19 S> */ B(Return),
B(LdaSmi), U8(-2),
B(Star), R(1),
- B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(3), U8(1),
- B(Star), R(4),
- B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(3), U8(1),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(4), U8(1),
B(Star), R(5),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(4), U8(1),
+ B(Star), R(6),
B(LdaZero),
- B(TestEqualStrict), R(5), U8(0),
- B(JumpIfTrue), U8(26),
+ B(TestEqualStrict), R(6), U8(0),
+ B(JumpIfTrue), U8(25),
B(LdaSmi), U8(2),
- B(TestEqualStrict), R(5), U8(0),
- B(JumpIfTrue), U8(16),
+ B(TestEqualStrict), R(6), U8(0),
+ B(JumpIfTrue), U8(15),
B(Jump), U8(2),
B(LdaTrue),
- B(Star), R(7),
- B(Mov), R(4), R(6),
- B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(6), U8(2),
+ B(Star), R(8),
+ B(Mov), R(5), R(7),
+ B(InvokeIntrinsic), U8(Runtime::k_CreateIterResultObject), R(7), U8(2),
/* 19 S> */ B(Return),
- B(Ldar), R(4),
+ B(Ldar), R(5),
/* 0 E> */ B(Throw),
B(LdaUndefined),
/* 19 S> */ B(Return),
@@ -832,78 +851,80 @@ snippet: "
import * as foo from \"bar\"
foo.f(foo, foo.x);
"
-frame size: 8
+frame size: 9
parameter count: 2
-bytecode array length: 164
+bytecode array length: 170
bytecodes: [
B(Ldar), R(new_target),
- B(JumpIfUndefined), U8(21),
+ B(JumpIfUndefined), U8(28),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetContext), R(new_target), U8(1),
+ B(PushContext), R(2),
B(ResumeGenerator), R(new_target),
B(Star), R(1),
B(LdaZero),
B(TestEqualStrict), R(1), U8(0),
B(JumpIfTrue), U8(73),
- B(LdaSmi), U8(77),
- B(Star), R(2),
- B(CallRuntime), U16(Runtime::kAbort), R(2), U8(1),
+ B(LdaSmi), U8(78),
+ B(Star), R(3),
+ B(CallRuntime), U16(Runtime::kAbort), R(3), U8(1),
B(LdaSmi), U8(-2),
B(Star), R(1),
B(LdaConstant), U8(0),
- B(Star), R(4),
- B(Mov), R(arg0), R(2),
- B(Mov), R(closure), R(3),
- B(CallRuntime), U16(Runtime::kPushModuleContext), R(2), U8(3),
+ B(Star), R(5),
+ B(Mov), R(arg0), R(3),
+ B(Mov), R(closure), R(4),
+ B(CallRuntime), U16(Runtime::kPushModuleContext), R(3), U8(3),
B(PushContext), R(0),
B(Ldar), R(this),
B(StaCurrentContextSlot), U8(4),
B(LdaZero),
- B(Star), R(2),
- B(CallRuntime), U16(Runtime::kGetModuleNamespace), R(2), U8(1),
+ B(Star), R(3),
+ B(CallRuntime), U16(Runtime::kGetModuleNamespace), R(3), U8(1),
B(StaCurrentContextSlot), U8(6),
/* 0 E> */ B(StackCheck),
B(LdaCurrentContextSlot), U8(4),
- B(Star), R(3),
- B(Mov), R(closure), R(2),
- /* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(2), U8(2),
+ B(Star), R(4),
+ B(Mov), R(closure), R(3),
+ /* 0 E> */ B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(3), U8(2),
B(StaCurrentContextSlot), U8(5),
- B(Star), R(2),
- B(LdaCurrentContextSlot), U8(5),
B(Star), R(3),
+ B(LdaCurrentContextSlot), U8(5),
+ B(Star), R(4),
B(LdaZero),
- B(SuspendGenerator), R(3),
- B(Ldar), R(2),
+ B(SuspendGenerator), R(4),
+ B(Ldar), R(3),
/* 45 S> */ B(Return),
B(LdaSmi), U8(-2),
B(Star), R(1),
- B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(3), U8(1),
- B(Star), R(4),
- B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(3), U8(1),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(4), U8(1),
B(Star), R(5),
+ B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(4), U8(1),
+ B(Star), R(6),
B(LdaZero),
- B(TestEqualStrict), R(5), U8(0),
- B(JumpIfTrue), U8(26),
+ B(TestEqualStrict), R(6), U8(0),
+ B(JumpIfTrue), U8(25),
B(LdaSmi), U8(2),
- B(TestEqualStrict), R(5), U8(0),
- B(JumpIfTrue), U8(16),
+ B(TestEqualStrict), R(6), U8(0),
+ B(JumpIfTrue), U8(15),
B(Jump), U8(2),
B(LdaTrue),
- B(Star), R(7),
- B(Mov), R(4), R(6),
- B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(6), U8(2),
+ B(Star), R(8),
+ B(Mov), R(5), R(7),
+ B(InvokeIntrinsic), U8(Runtime::k_CreateIterResultObject), R(7), U8(2),
/* 45 S> */ B(Return),
- B(Ldar), R(4),
+ B(Ldar), R(5),
/* 0 E> */ B(Throw),
/* 27 S> */ B(LdaCurrentContextSlot), U8(6),
- B(Star), R(3),
- /* 30 E> */ B(LdaNamedProperty), R(3), U8(1), U8(4),
- B(Star), R(2),
- B(LdaCurrentContextSlot), U8(6),
B(Star), R(4),
+ /* 30 E> */ B(LdaNamedProperty), R(4), U8(1), U8(4),
+ B(Star), R(3),
B(LdaCurrentContextSlot), U8(6),
B(Star), R(5),
- /* 41 E> */ B(LdaNamedProperty), R(5), U8(2), U8(6),
- B(Star), R(5),
- /* 31 E> */ B(CallProperty), R(2), R(3), U8(3), U8(2),
+ B(LdaCurrentContextSlot), U8(6),
+ B(Star), R(6),
+ /* 41 E> */ B(LdaNamedProperty), R(6), U8(2), U8(6),
+ B(Star), R(6),
+ /* 31 E> */ B(CallProperty), R(3), R(4), U8(3), U8(2),
B(LdaUndefined),
/* 45 S> */ B(Return),
]
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/ObjectLiterals.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/ObjectLiterals.golden
index 7f81d82a2d..75c6ff57be 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/ObjectLiterals.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/ObjectLiterals.golden
@@ -78,7 +78,7 @@ bytecodes: [
/* 42 S> */ B(LdaSmi), U8(1),
B(Star), R(0),
/* 45 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(1), R(1),
- /* 67 E> */ B(AddSmi), U8(1), R(0), U8(2),
+ /* 69 E> */ B(AddSmi), U8(1), R(0), U8(2),
B(StaNamedPropertySloppy), R(1), U8(1), U8(3),
B(Ldar), R(1),
/* 76 S> */ B(Return),
@@ -96,12 +96,12 @@ snippet: "
"
frame size: 1
parameter count: 1
-bytecode array length: 16
+bytecode array length: 17
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(1), R(0),
- B(CreateClosure), U8(1), U8(2),
- B(StaNamedPropertySloppy), R(0), U8(2), U8(2),
+ B(CreateClosure), U8(1), U8(2), U8(2),
+ B(StaNamedPropertySloppy), R(0), U8(2), U8(3),
B(Ldar), R(0),
/* 67 S> */ B(Return),
]
@@ -119,12 +119,12 @@ snippet: "
"
frame size: 1
parameter count: 1
-bytecode array length: 16
+bytecode array length: 17
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(1), R(0),
- B(CreateClosure), U8(1), U8(2),
- B(StaNamedPropertySloppy), R(0), U8(2), U8(2),
+ B(CreateClosure), U8(1), U8(2), U8(2),
+ B(StaNamedPropertySloppy), R(0), U8(2), U8(3),
B(Ldar), R(0),
/* 68 S> */ B(Return),
]
@@ -142,13 +142,13 @@ snippet: "
"
frame size: 6
parameter count: 1
-bytecode array length: 32
+bytecode array length: 33
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(1), R(0),
B(LdaConstant), U8(1),
B(Star), R(2),
- B(CreateClosure), U8(2), U8(2),
+ B(CreateClosure), U8(2), U8(2), U8(2),
B(Star), R(3),
B(LdaNull),
B(Star), R(4),
@@ -173,15 +173,15 @@ snippet: "
"
frame size: 6
parameter count: 1
-bytecode array length: 34
+bytecode array length: 36
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(1), R(0),
B(LdaConstant), U8(1),
B(Star), R(2),
- B(CreateClosure), U8(2), U8(2),
+ B(CreateClosure), U8(2), U8(2), U8(2),
B(Star), R(3),
- B(CreateClosure), U8(3), U8(2),
+ B(CreateClosure), U8(3), U8(3), U8(2),
B(Star), R(4),
B(LdaZero),
B(Star), R(5),
@@ -205,7 +205,7 @@ snippet: "
"
frame size: 6
parameter count: 1
-bytecode array length: 32
+bytecode array length: 33
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(1), R(0),
@@ -213,7 +213,7 @@ bytecodes: [
B(Star), R(2),
B(LdaNull),
B(Star), R(3),
- B(CreateClosure), U8(2), U8(2),
+ B(CreateClosure), U8(2), U8(2), U8(2),
B(Star), R(4),
B(LdaZero),
B(Star), R(5),
@@ -285,24 +285,19 @@ handlers: [
snippet: "
var a = 'test'; return { [a]: 1 };
"
-frame size: 7
+frame size: 4
parameter count: 1
-bytecode array length: 33
+bytecode array length: 24
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaConstant), U8(0),
B(Star), R(0),
/* 50 S> */ B(CreateObjectLiteral), U8(1), U8(0), U8(35), R(1),
- /* 60 E> */ B(ToName), R(3),
+ /* 60 E> */ B(ToName), R(2),
B(LdaSmi), U8(1),
- B(Star), R(4),
- B(LdaZero),
- B(Star), R(5),
- B(LdaZero),
- B(Star), R(6),
- B(Mov), R(1), R(2),
- B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(2), U8(5),
- B(Ldar), R(2),
+ B(Star), R(3),
+ B(StaDataPropertyInLiteral), R(1), R(2), U8(0), U8(2),
+ B(Ldar), R(1),
/* 69 S> */ B(Return),
]
constant pool: [
@@ -316,25 +311,20 @@ handlers: [
snippet: "
var a = 'test'; return { val: a, [a]: 1 };
"
-frame size: 7
+frame size: 4
parameter count: 1
-bytecode array length: 37
+bytecode array length: 28
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaConstant), U8(0),
B(Star), R(0),
/* 50 S> */ B(CreateObjectLiteral), U8(1), U8(0), U8(1), R(1),
/* 64 E> */ B(StaNamedPropertySloppy), R(1), U8(2), U8(2),
- /* 68 E> */ B(ToName), R(3),
+ /* 68 E> */ B(ToName), R(2),
B(LdaSmi), U8(1),
- B(Star), R(4),
- B(LdaZero),
- B(Star), R(5),
- B(LdaZero),
- B(Star), R(6),
- B(Mov), R(1), R(2),
- B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(2), U8(5),
- B(Ldar), R(2),
+ B(Star), R(3),
+ B(StaDataPropertyInLiteral), R(1), R(2), U8(0), U8(4),
+ B(Ldar), R(1),
/* 77 S> */ B(Return),
]
constant pool: [
@@ -349,24 +339,20 @@ handlers: [
snippet: "
var a = 'test'; return { [a]: 1, __proto__: {} };
"
-frame size: 7
+frame size: 5
parameter count: 1
-bytecode array length: 46
+bytecode array length: 40
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaConstant), U8(0),
B(Star), R(0),
/* 50 S> */ B(CreateObjectLiteral), U8(1), U8(1), U8(35), R(1),
- /* 60 E> */ B(ToName), R(3),
+ /* 60 E> */ B(ToName), R(2),
B(LdaSmi), U8(1),
- B(Star), R(4),
- B(LdaZero),
- B(Star), R(5),
- B(LdaZero),
- B(Star), R(6),
- B(Mov), R(1), R(2),
- B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(2), U8(5),
+ B(Star), R(3),
+ B(StaDataPropertyInLiteral), R(1), R(2), U8(0), U8(2),
B(CreateObjectLiteral), U8(1), U8(0), U8(35), R(4),
+ B(Mov), R(1), R(2),
B(Mov), R(4), R(3),
B(CallRuntime), U16(Runtime::kInternalSetPrototype), R(2), U8(2),
B(Ldar), R(2),
@@ -383,33 +369,29 @@ handlers: [
snippet: "
var n = 'name'; return { [n]: 'val', get a() { }, set a(b) {} };
"
-frame size: 7
+frame size: 6
parameter count: 1
-bytecode array length: 67
+bytecode array length: 63
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaConstant), U8(0),
B(Star), R(0),
/* 50 S> */ B(CreateObjectLiteral), U8(1), U8(0), U8(35), R(1),
- /* 60 E> */ B(ToName), R(3),
+ /* 60 E> */ B(ToName), R(2),
B(LdaConstant), U8(2),
- B(Star), R(4),
- B(LdaZero),
- B(Star), R(5),
- B(LdaZero),
- B(Star), R(6),
- B(Mov), R(1), R(2),
- B(CallRuntime), U16(Runtime::kDefineDataPropertyInLiteral), R(2), U8(5),
+ B(Star), R(3),
+ B(StaDataPropertyInLiteral), R(1), R(2), U8(0), U8(4),
B(LdaConstant), U8(3),
B(ToName), R(3),
- B(CreateClosure), U8(4), U8(2),
+ B(CreateClosure), U8(4), U8(2), U8(2),
B(Star), R(4),
B(LdaZero),
B(Star), R(5),
+ B(Mov), R(1), R(2),
B(CallRuntime), U16(Runtime::kDefineGetterPropertyUnchecked), R(2), U8(4),
B(LdaConstant), U8(3),
B(ToName), R(3),
- B(CreateClosure), U8(5), U8(2),
+ B(CreateClosure), U8(5), U8(3), U8(2),
B(Star), R(4),
B(LdaZero),
B(Star), R(5),
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/OuterContextVariables.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/OuterContextVariables.golden
index 30b148b1d6..52ea01f910 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/OuterContextVariables.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/OuterContextVariables.golden
@@ -26,7 +26,7 @@ bytecodes: [
/* 102 S> */ B(LdaContextSlot), R(context), U8(4), U8(1),
B(Star), R(0),
B(LdaCurrentContextSlot), U8(4),
- /* 120 E> */ B(Mul), R(0), U8(2),
+ /* 118 E> */ B(Mul), R(0), U8(2),
/* 130 S> */ B(Return),
]
constant pool: [
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/PrimitiveExpressions.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/PrimitiveExpressions.golden
index adcf911cdd..90fb7b9dbb 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/PrimitiveExpressions.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/PrimitiveExpressions.golden
@@ -30,12 +30,13 @@ snippet: "
"
frame size: 1
parameter count: 1
-bytecode array length: 9
+bytecode array length: 10
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero),
B(Star), R(0),
- /* 45 S> */ B(AddSmi), U8(3), R(0), U8(2),
+ /* 45 S> */ B(LdaSmi), U8(3),
+ /* 54 E> */ B(Add), R(0), U8(2),
/* 59 S> */ B(Return),
]
constant pool: [
@@ -49,12 +50,13 @@ snippet: "
"
frame size: 1
parameter count: 1
-bytecode array length: 9
+bytecode array length: 10
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero),
B(Star), R(0),
- /* 45 S> */ B(SubSmi), U8(3), R(0), U8(2),
+ /* 45 S> */ B(LdaSmi), U8(3),
+ /* 54 E> */ B(Sub), R(0), U8(2),
/* 59 S> */ B(Return),
]
constant pool: [
@@ -74,7 +76,7 @@ bytecodes: [
/* 42 S> */ B(LdaSmi), U8(4),
B(Star), R(0),
/* 45 S> */ B(LdaSmi), U8(3),
- B(Mul), R(0), U8(2),
+ /* 54 E> */ B(Mul), R(0), U8(2),
/* 59 S> */ B(Return),
]
constant pool: [
@@ -94,7 +96,7 @@ bytecodes: [
/* 42 S> */ B(LdaSmi), U8(4),
B(Star), R(0),
/* 45 S> */ B(LdaSmi), U8(3),
- B(Div), R(0), U8(2),
+ /* 54 E> */ B(Div), R(0), U8(2),
/* 59 S> */ B(Return),
]
constant pool: [
@@ -114,7 +116,7 @@ bytecodes: [
/* 42 S> */ B(LdaSmi), U8(4),
B(Star), R(0),
/* 45 S> */ B(LdaSmi), U8(3),
- B(Mod), R(0), U8(2),
+ /* 54 E> */ B(Mod), R(0), U8(2),
/* 59 S> */ B(Return),
]
constant pool: [
@@ -128,12 +130,13 @@ snippet: "
"
frame size: 1
parameter count: 1
-bytecode array length: 10
+bytecode array length: 11
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(1),
B(Star), R(0),
- /* 45 S> */ B(BitwiseOrSmi), U8(2), R(0), U8(2),
+ /* 45 S> */ B(LdaSmi), U8(2),
+ /* 54 E> */ B(BitwiseOr), R(0), U8(2),
/* 59 S> */ B(Return),
]
constant pool: [
@@ -153,7 +156,7 @@ bytecodes: [
/* 42 S> */ B(LdaSmi), U8(1),
B(Star), R(0),
/* 45 S> */ B(LdaSmi), U8(2),
- B(BitwiseXor), R(0), U8(2),
+ /* 54 E> */ B(BitwiseXor), R(0), U8(2),
/* 59 S> */ B(Return),
]
constant pool: [
@@ -167,12 +170,13 @@ snippet: "
"
frame size: 1
parameter count: 1
-bytecode array length: 10
+bytecode array length: 11
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(1),
B(Star), R(0),
- /* 45 S> */ B(BitwiseAndSmi), U8(2), R(0), U8(2),
+ /* 45 S> */ B(LdaSmi), U8(2),
+ /* 54 E> */ B(BitwiseAnd), R(0), U8(2),
/* 59 S> */ B(Return),
]
constant pool: [
@@ -186,12 +190,13 @@ snippet: "
"
frame size: 1
parameter count: 1
-bytecode array length: 10
+bytecode array length: 11
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(10),
B(Star), R(0),
- /* 46 S> */ B(ShiftLeftSmi), U8(3), R(0), U8(2),
+ /* 46 S> */ B(LdaSmi), U8(3),
+ /* 55 E> */ B(ShiftLeft), R(0), U8(2),
/* 61 S> */ B(Return),
]
constant pool: [
@@ -205,12 +210,13 @@ snippet: "
"
frame size: 1
parameter count: 1
-bytecode array length: 10
+bytecode array length: 11
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(10),
B(Star), R(0),
- /* 46 S> */ B(ShiftRightSmi), U8(3), R(0), U8(2),
+ /* 46 S> */ B(LdaSmi), U8(3),
+ /* 55 E> */ B(ShiftRight), R(0), U8(2),
/* 61 S> */ B(Return),
]
constant pool: [
@@ -230,7 +236,7 @@ bytecodes: [
/* 42 S> */ B(LdaSmi), U8(10),
B(Star), R(0),
/* 46 S> */ B(LdaSmi), U8(3),
- B(ShiftRightLogical), R(0), U8(2),
+ /* 55 E> */ B(ShiftRightLogical), R(0), U8(2),
/* 62 S> */ B(Return),
]
constant pool: [
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/PropertyCall.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/PropertyCall.golden
index e401dbf88b..f0a51af8bd 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/PropertyCall.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/PropertyCall.golden
@@ -67,7 +67,7 @@ bytecodes: [
/* 27 E> */ B(LdaNamedProperty), R(arg0), U8(0), U8(4),
B(Star), R(0),
B(Ldar), R(arg1),
- /* 37 E> */ B(Add), R(arg1), U8(6),
+ /* 35 E> */ B(Add), R(arg1), U8(6),
B(Star), R(2),
B(Mov), R(arg0), R(1),
B(Mov), R(arg1), R(3),
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/RemoveRedundantLdar.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/RemoveRedundantLdar.golden
index de6e8935b3..1c806b7f46 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/RemoveRedundantLdar.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/RemoveRedundantLdar.golden
@@ -23,7 +23,7 @@ bytecodes: [
B(Star), R(0),
/* 48 E> */ B(StackCheck),
/* 64 S> */ B(Ldar), R(0),
- /* 78 E> */ B(Add), R(0), U8(2),
+ /* 76 E> */ B(Add), R(0), U8(2),
B(Star), R(0),
/* 86 S> */ B(LdaSmi), U8(10),
/* 95 E> */ B(TestGreaterThan), R(0), U8(3),
@@ -56,7 +56,7 @@ bytecodes: [
B(Star), R(0),
/* 48 E> */ B(StackCheck),
/* 55 S> */ B(Nop),
- /* 69 E> */ B(Add), R(0), U8(2),
+ /* 67 E> */ B(Add), R(0), U8(2),
B(Star), R(0),
/* 77 S> */ B(LdaSmi), U8(10),
/* 86 E> */ B(TestGreaterThan), R(0), U8(3),
@@ -84,7 +84,7 @@ bytecodes: [
/* 45 S> */ B(LdaSmi), U8(1),
B(Star), R(0),
/* 50 S> */ B(Nop),
- /* 64 E> */ B(Add), R(0), U8(2),
+ /* 62 E> */ B(Add), R(0), U8(2),
B(Star), R(0),
/* 72 S> */ B(Nop),
/* 85 S> */ B(Return),
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/SuperCallAndSpread.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/SuperCallAndSpread.golden
new file mode 100644
index 0000000000..2dd9ec5383
--- /dev/null
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/SuperCallAndSpread.golden
@@ -0,0 +1,155 @@
+#
+# Autogenerated by generate-bytecode-expectations.
+#
+
+---
+wrap: no
+test function name: test
+
+---
+snippet: "
+ var test;
+ (function() {
+ class A {
+ constructor(...args) { this.baseArgs = args; }
+ }
+ class B extends A {}
+ test = new B(1, 2, 3).constructor;
+ })();
+"
+frame size: 7
+parameter count: 1
+bytecode array length: 29
+bytecodes: [
+ B(CreateRestParameter),
+ B(Star), R(2),
+ B(Mov), R(closure), R(1),
+ B(Mov), R(new_target), R(0),
+ B(Ldar), R(new_target),
+ /* 93 E> */ B(StackCheck),
+ /* 93 S> */ B(Ldar), R(1),
+ B(GetSuperConstructor), R(3),
+ B(Mov), R(3), R(4),
+ B(Mov), R(0), R(5),
+ B(Mov), R(2), R(6),
+ /* 93 E> */ B(NewWithSpread), R(4), U8(3),
+ /* 93 S> */ B(Return),
+]
+constant pool: [
+]
+handlers: [
+]
+
+---
+snippet: "
+ var test;
+ (function() {
+ class A {
+ constructor(...args) { this.baseArgs = args; }
+ }
+ class B extends A {
+ constructor(...args) { super(1, ...args); }
+ }
+ test = new B(1, 2, 3).constructor;
+ })();
+"
+frame size: 8
+parameter count: 1
+bytecode array length: 62
+bytecodes: [
+ B(CreateRestParameter),
+ B(Star), R(2),
+ B(Mov), R(closure), R(1),
+ B(Mov), R(new_target), R(0),
+ B(Ldar), R(new_target),
+ /* 128 E> */ B(StackCheck),
+ /* 140 S> */ B(Ldar), R(1),
+ B(GetSuperConstructor), R(3),
+ B(LdaSmi), U8(1),
+ B(Star), R(6),
+ B(Mov), R(3), R(4),
+ B(Mov), R(0), R(5),
+ B(Mov), R(2), R(7),
+ /* 140 E> */ B(NewWithSpread), R(4), U8(4),
+ B(Star), R(3),
+ B(Ldar), R(this),
+ B(JumpIfNotHole), U8(4),
+ B(Jump), U8(7),
+ /* 140 E> */ B(CallRuntime), U16(Runtime::kThrowSuperAlreadyCalledError), R(0), U8(0),
+ B(Mov), R(3), R(this),
+ B(Ldar), R(this),
+ B(JumpIfNotHole), U8(11),
+ B(LdaConstant), U8(0),
+ B(Star), R(3),
+ B(CallRuntime), U16(Runtime::kThrowReferenceError), R(3), U8(1),
+ /* 159 S> */ B(Return),
+]
+constant pool: [
+ ONE_BYTE_INTERNALIZED_STRING_TYPE ["this"],
+]
+handlers: [
+]
+
+---
+snippet: "
+ var test;
+ (function() {
+ class A {
+ constructor(...args) { this.baseArgs = args; }
+ }
+ class B extends A {
+ constructor(...args) { super(1, ...args, 1); }
+ }
+ test = new B(1, 2, 3).constructor;
+ })();
+"
+frame size: 9
+parameter count: 1
+bytecode array length: 92
+bytecodes: [
+ B(CreateRestParameter),
+ B(Star), R(2),
+ B(Mov), R(closure), R(1),
+ B(Mov), R(new_target), R(0),
+ B(Ldar), R(new_target),
+ /* 128 E> */ B(StackCheck),
+ /* 140 S> */ B(LdaUndefined),
+ B(Star), R(3),
+ /* 140 E> */ B(CallRuntime), U16(Runtime::k_GetSuperConstructor), R(1), U8(1),
+ B(Star), R(4),
+ B(LdaUndefined),
+ B(Star), R(5),
+ B(CreateArrayLiteral), U8(0), U8(0), U8(9),
+ B(Star), R(6),
+ B(LdaUndefined),
+ B(Star), R(7),
+ B(Mov), R(2), R(8),
+ /* 152 E> */ B(CallJSRuntime), U8(%spread_iterable), R(7), U8(2),
+ B(Star), R(7),
+ B(CreateArrayLiteral), U8(1), U8(1), U8(9),
+ B(Star), R(8),
+ B(CallJSRuntime), U8(%spread_arguments), R(5), U8(4),
+ B(Star), R(5),
+ B(Mov), R(0), R(6),
+ /* 140 E> */ B(CallJSRuntime), U8(%reflect_construct), R(3), U8(4),
+ B(Star), R(3),
+ B(Ldar), R(this),
+ B(JumpIfNotHole), U8(4),
+ B(Jump), U8(7),
+ /* 140 E> */ B(CallRuntime), U16(Runtime::kThrowSuperAlreadyCalledError), R(0), U8(0),
+ B(Mov), R(3), R(this),
+ B(Ldar), R(this),
+ B(JumpIfNotHole), U8(11),
+ B(LdaConstant), U8(2),
+ B(Star), R(3),
+ B(CallRuntime), U16(Runtime::kThrowReferenceError), R(3), U8(1),
+ /* 162 S> */ B(Return),
+]
+constant pool: [
+ CONSTANT_ELEMENTS_PAIR_TYPE,
+ CONSTANT_ELEMENTS_PAIR_TYPE,
+ ONE_BYTE_INTERNALIZED_STRING_TYPE ["this"],
+]
+handlers: [
+]
+
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/Switch.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/Switch.golden
index 9334dbebfd..77bee13e14 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/Switch.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/Switch.golden
@@ -493,7 +493,7 @@ bytecodes: [
B(TestEqualStrict), R(3), U8(6),
B(JumpIfTrue), U8(34),
B(Jump), U8(36),
- /* 77 E> */ B(AddSmi), U8(1), R(0), U8(2),
+ /* 79 E> */ B(AddSmi), U8(1), R(0), U8(2),
B(Star), R(1),
/* 70 S> */ B(LdaSmi), U8(2),
B(TestEqualStrict), R(1), U8(3),
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/TopLevelObjectLiterals.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/TopLevelObjectLiterals.golden
index d7b7917baf..1594422e49 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/TopLevelObjectLiterals.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/TopLevelObjectLiterals.golden
@@ -12,7 +12,7 @@ snippet: "
"
frame size: 4
parameter count: 1
-bytecode array length: 42
+bytecode array length: 43
bytecodes: [
B(LdaConstant), U8(0),
B(Star), R(1),
@@ -26,8 +26,8 @@ bytecodes: [
B(LdaZero),
B(CreateObjectLiteral), U8(2), U8(0), U8(1), R(3),
B(Star), R(2),
- B(CreateClosure), U8(3), U8(0),
- B(StaNamedPropertySloppy), R(3), U8(4), U8(4),
+ B(CreateClosure), U8(3), U8(4), U8(0),
+ B(StaNamedPropertySloppy), R(3), U8(4), U8(5),
B(CallRuntime), U16(Runtime::kInitializeVarGlobal), R(1), U8(3),
B(LdaUndefined),
/* 33 S> */ B(Return),
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/TryCatch.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/TryCatch.golden
index c2f6113e71..b687ed24ca 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/TryCatch.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/TryCatch.golden
@@ -11,18 +11,19 @@ snippet: "
"
frame size: 3
parameter count: 1
-bytecode array length: 35
+bytecode array length: 32
bytecodes: [
/* 30 E> */ B(StackCheck),
B(Mov), R(context), R(1),
/* 40 S> */ B(LdaSmi), U8(1),
/* 75 S> */ B(Return),
- B(Jump), U8(26),
+ B(Jump), U8(23),
B(Star), R(2),
B(Ldar), R(closure),
B(CreateCatchContext), R(2), U8(0), U8(1),
B(Star), R(1),
- B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
+ B(LdaTheHole),
+ B(SetPendingMessage),
B(Ldar), R(1),
B(PushContext), R(0),
/* 63 S> */ B(LdaSmi), U8(2),
@@ -47,30 +48,32 @@ snippet: "
"
frame size: 4
parameter count: 1
-bytecode array length: 67
+bytecode array length: 61
bytecodes: [
/* 30 E> */ B(StackCheck),
B(Mov), R(context), R(2),
/* 47 S> */ B(LdaSmi), U8(1),
B(Star), R(0),
- B(Jump), U8(23),
+ B(Jump), U8(20),
B(Star), R(3),
B(Ldar), R(closure),
/* 49 E> */ B(CreateCatchContext), R(3), U8(0), U8(1),
B(Star), R(2),
- B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
+ B(LdaTheHole),
+ B(SetPendingMessage),
B(Ldar), R(2),
B(PushContext), R(1),
B(PopContext), R(1),
B(Mov), R(context), R(2),
/* 75 S> */ B(LdaSmi), U8(2),
B(Star), R(0),
- B(Jump), U8(27),
+ B(Jump), U8(24),
B(Star), R(3),
B(Ldar), R(closure),
/* 77 E> */ B(CreateCatchContext), R(3), U8(2), U8(3),
B(Star), R(2),
- B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
+ B(LdaTheHole),
+ B(SetPendingMessage),
B(Ldar), R(2),
B(PushContext), R(1),
/* 95 S> */ B(LdaSmi), U8(3),
@@ -87,6 +90,6 @@ constant pool: [
]
handlers: [
[4, 8, 10],
- [34, 38, 40],
+ [31, 35, 37],
]
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/TryFinally.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/TryFinally.golden
index 61deb6e69c..b85ae8c51a 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/TryFinally.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/TryFinally.golden
@@ -12,7 +12,7 @@ snippet: "
"
frame size: 4
parameter count: 1
-bytecode array length: 52
+bytecode array length: 47
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(1),
@@ -26,11 +26,13 @@ bytecodes: [
B(Star), R(2),
B(LdaZero),
B(Star), R(1),
- /* 53 E> */ B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
+ B(LdaTheHole),
+ /* 53 E> */ B(SetPendingMessage),
B(Star), R(3),
/* 70 S> */ B(LdaSmi), U8(3),
B(Star), R(0),
- /* 72 E> */ B(CallRuntime), U16(Runtime::kInterpreterSetPendingMessage), R(3), U8(1),
+ B(Ldar), R(3),
+ /* 72 E> */ B(SetPendingMessage),
B(LdaZero),
B(TestEqualStrict), R(1), U8(0),
B(JumpIfTrue), U8(4),
@@ -53,7 +55,7 @@ snippet: "
"
frame size: 7
parameter count: 1
-bytecode array length: 82
+bytecode array length: 74
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(1),
@@ -62,12 +64,13 @@ bytecodes: [
B(Mov), R(context), R(5),
/* 51 S> */ B(LdaSmi), U8(2),
B(Star), R(0),
- B(Jump), U8(27),
+ B(Jump), U8(24),
B(Star), R(6),
B(Ldar), R(closure),
/* 53 E> */ B(CreateCatchContext), R(6), U8(0), U8(1),
B(Star), R(5),
- B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
+ B(LdaTheHole),
+ B(SetPendingMessage),
B(Ldar), R(5),
B(PushContext), R(1),
/* 71 S> */ B(LdaSmi), U8(20),
@@ -79,11 +82,13 @@ bytecodes: [
B(Star), R(3),
B(LdaZero),
B(Star), R(2),
- /* 73 E> */ B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
+ B(LdaTheHole),
+ /* 73 E> */ B(SetPendingMessage),
B(Star), R(4),
/* 90 S> */ B(LdaSmi), U8(3),
B(Star), R(0),
- /* 92 E> */ B(CallRuntime), U16(Runtime::kInterpreterSetPendingMessage), R(4), U8(1),
+ B(Ldar), R(4),
+ /* 92 E> */ B(SetPendingMessage),
B(LdaZero),
B(TestEqualStrict), R(2), U8(0),
B(JumpIfTrue), U8(4),
@@ -98,7 +103,7 @@ constant pool: [
FIXED_ARRAY_TYPE,
]
handlers: [
- [8, 42, 48],
+ [8, 39, 45],
[11, 15, 17],
]
@@ -110,7 +115,7 @@ snippet: "
"
frame size: 8
parameter count: 1
-bytecode array length: 108
+bytecode array length: 97
bytecodes: [
/* 30 E> */ B(StackCheck),
B(Mov), R(context), R(4),
@@ -118,23 +123,25 @@ bytecodes: [
B(Mov), R(context), R(6),
/* 55 S> */ B(LdaSmi), U8(1),
B(Star), R(0),
- B(Jump), U8(27),
+ B(Jump), U8(24),
B(Star), R(7),
B(Ldar), R(closure),
/* 57 E> */ B(CreateCatchContext), R(7), U8(0), U8(1),
B(Star), R(6),
- B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
+ B(LdaTheHole),
+ B(SetPendingMessage),
B(Ldar), R(6),
B(PushContext), R(1),
/* 74 S> */ B(LdaSmi), U8(2),
B(Star), R(0),
B(PopContext), R(1),
- B(Jump), U8(27),
+ B(Jump), U8(24),
B(Star), R(6),
B(Ldar), R(closure),
/* 76 E> */ B(CreateCatchContext), R(6), U8(0), U8(2),
B(Star), R(5),
- B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
+ B(LdaTheHole),
+ B(SetPendingMessage),
B(Ldar), R(5),
B(PushContext), R(1),
/* 95 S> */ B(LdaSmi), U8(20),
@@ -146,11 +153,13 @@ bytecodes: [
B(Star), R(3),
B(LdaZero),
B(Star), R(2),
- /* 97 E> */ B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
+ B(LdaTheHole),
+ /* 97 E> */ B(SetPendingMessage),
B(Star), R(4),
/* 114 S> */ B(LdaSmi), U8(3),
B(Star), R(0),
- /* 116 E> */ B(CallRuntime), U16(Runtime::kInterpreterSetPendingMessage), R(4), U8(1),
+ B(Ldar), R(4),
+ /* 116 E> */ B(SetPendingMessage),
B(LdaZero),
B(TestEqualStrict), R(2), U8(0),
B(JumpIfTrue), U8(4),
@@ -166,8 +175,8 @@ constant pool: [
FIXED_ARRAY_TYPE,
]
handlers: [
- [4, 68, 74],
- [7, 41, 43],
+ [4, 62, 68],
+ [7, 38, 40],
[10, 14, 16],
]
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/Typeof.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/Typeof.golden
index 5e15e5981e..d5ab090594 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/Typeof.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/Typeof.golden
@@ -39,14 +39,15 @@ snippet: "
"
frame size: 0
parameter count: 1
-bytecode array length: 5
+bytecode array length: 6
bytecodes: [
/* 22 E> */ B(StackCheck),
- /* 28 S> */ B(LdaGlobalInsideTypeof), U8(2),
+ /* 28 S> */ B(LdaGlobalInsideTypeof), U8(0), U8(2),
B(TypeOf),
/* 46 S> */ B(Return),
]
constant pool: [
+ ONE_BYTE_INTERNALIZED_STRING_TYPE ["x"],
]
handlers: [
]
diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/UnaryOperators.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/UnaryOperators.golden
index 660a01b242..1620f93f5e 100644
--- a/deps/v8/test/cctest/interpreter/bytecode_expectations/UnaryOperators.golden
+++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/UnaryOperators.golden
@@ -15,18 +15,19 @@ snippet: "
"
frame size: 1
parameter count: 1
-bytecode array length: 24
+bytecode array length: 25
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero),
B(Star), R(0),
/* 54 S> */ B(LdaSmi), U8(10),
/* 54 E> */ B(TestEqual), R(0), U8(2),
- B(JumpIfTrue), U8(12),
+ B(JumpIfTrue), U8(13),
/* 45 E> */ B(StackCheck),
- /* 65 S> */ B(AddSmi), U8(10), R(0), U8(3),
+ /* 65 S> */ B(LdaSmi), U8(10),
+ /* 71 E> */ B(Add), R(0), U8(3),
B(Star), R(0),
- B(JumpLoop), U8(-14), U8(0),
+ B(JumpLoop), U8(-15), U8(0),
/* 79 S> */ B(Ldar), R(0),
/* 89 S> */ B(Return),
]
@@ -79,7 +80,7 @@ bytecodes: [
/* 42 S> */ B(LdaSmi), U8(101),
B(Star), R(0),
/* 47 S> */ B(LdaSmi), U8(3),
- B(Mul), R(0), U8(2),
+ /* 61 E> */ B(Mul), R(0), U8(2),
B(LdaUndefined),
/* 67 S> */ B(Return),
]
@@ -102,9 +103,9 @@ bytecodes: [
/* 42 S> */ B(Wide), B(LdaSmi), U16(1234),
B(Star), R(0),
/* 56 S> */ B(Nop),
- /* 66 E> */ B(Mul), R(0), U8(2),
+ /* 64 E> */ B(Mul), R(0), U8(2),
B(Star), R(2),
- B(SubSmi), U8(1), R(2), U8(3),
+ /* 68 E> */ B(SubSmi), U8(1), R(2), U8(3),
B(LdaUndefined),
B(Star), R(1),
/* 74 S> */ B(Nop),
@@ -128,7 +129,7 @@ bytecodes: [
/* 42 S> */ B(LdaSmi), U8(13),
B(Star), R(0),
/* 46 S> */ B(LdaSmi), U8(-1),
- B(BitwiseXor), R(0), U8(2),
+ /* 53 E> */ B(BitwiseXor), R(0), U8(2),
/* 57 S> */ B(Return),
]
constant pool: [
@@ -149,7 +150,7 @@ bytecodes: [
/* 42 S> */ B(LdaSmi), U8(13),
B(Star), R(0),
/* 46 S> */ B(LdaSmi), U8(1),
- B(Mul), R(0), U8(2),
+ /* 53 E> */ B(Mul), R(0), U8(2),
/* 57 S> */ B(Return),
]
constant pool: [
@@ -170,7 +171,7 @@ bytecodes: [
/* 42 S> */ B(LdaSmi), U8(13),
B(Star), R(0),
/* 46 S> */ B(LdaSmi), U8(-1),
- B(Mul), R(0), U8(2),
+ /* 53 E> */ B(Mul), R(0), U8(2),
/* 57 S> */ B(Return),
]
constant pool: [
diff --git a/deps/v8/test/cctest/interpreter/interpreter-tester.cc b/deps/v8/test/cctest/interpreter/interpreter-tester.cc
index df60c452cd..3896ff53ad 100644
--- a/deps/v8/test/cctest/interpreter/interpreter-tester.cc
+++ b/deps/v8/test/cctest/interpreter/interpreter-tester.cc
@@ -4,6 +4,8 @@
#include "test/cctest/interpreter/interpreter-tester.h"
+#include "src/objects-inl.h"
+
namespace v8 {
namespace internal {
namespace interpreter {
@@ -23,8 +25,6 @@ InterpreterTester::InterpreterTester(
feedback_vector_(feedback_vector) {
i::FLAG_ignition = true;
i::FLAG_always_opt = false;
- // Ensure handler table is generated.
- isolate->interpreter()->Initialize();
}
InterpreterTester::InterpreterTester(
diff --git a/deps/v8/test/cctest/interpreter/test-bytecode-generator.cc b/deps/v8/test/cctest/interpreter/test-bytecode-generator.cc
index 5a20d86297..b43384e946 100644
--- a/deps/v8/test/cctest/interpreter/test-bytecode-generator.cc
+++ b/deps/v8/test/cctest/interpreter/test-bytecode-generator.cc
@@ -9,6 +9,7 @@
#include "src/interpreter/bytecode-array-iterator.h"
#include "src/interpreter/bytecode-generator.h"
#include "src/interpreter/interpreter.h"
+#include "src/objects-inl.h"
#include "test/cctest/cctest.h"
#include "test/cctest/interpreter/bytecode-expectations-printer.h"
#include "test/cctest/test-feedback-vector.h"
@@ -74,7 +75,6 @@ class InitializedIgnitionHandleScope : public InitializedHandleScope {
i::FLAG_ignition = true;
i::FLAG_always_opt = false;
i::FLAG_allow_natives_syntax = true;
- CcTest::i_isolate()->interpreter()->Initialize();
}
};
@@ -1746,6 +1746,54 @@ TEST(RemoveRedundantLdar) {
LoadGolden("RemoveRedundantLdar.golden")));
}
+TEST(GenerateTestUndetectable) {
+ InitializedIgnitionHandleScope scope;
+ BytecodeExpectationsPrinter printer(CcTest::isolate());
+ const char* snippets[] = {
+ "var obj_a = {val:1};\n"
+ "var b = 10;\n"
+ "if (obj_a == null) { b = 20;}\n"
+ "return b;\n",
+
+ "var obj_a = {val:1};\n"
+ "var b = 10;\n"
+ "if (obj_a == undefined) { b = 20;}\n"
+ "return b;\n",
+
+ "var obj_a = {val:1};\n"
+ "var b = 10;\n"
+ "if (obj_a != null) { b = 20;}\n"
+ "return b;\n",
+
+ "var obj_a = {val:1};\n"
+ "var b = 10;\n"
+ "if (obj_a != undefined) { b = 20;}\n"
+ "return b;\n",
+
+ "var obj_a = {val:1};\n"
+ "var b = 10;\n"
+ "if (obj_a === null) { b = 20;}\n"
+ "return b;\n",
+
+ "var obj_a = {val:1};\n"
+ "var b = 10;\n"
+ "if (obj_a === undefined) { b = 20;}\n"
+ "return b;\n",
+
+ "var obj_a = {val:1};\n"
+ "var b = 10;\n"
+ "if (obj_a !== null) { b = 20;}\n"
+ "return b;\n",
+
+ "var obj_a = {val:1};\n"
+ "var b = 10;\n"
+ "if (obj_a !== undefined) { b = 20;}\n"
+ "return b;\n"};
+
+ CHECK(CompareTexts(BuildActual(printer, snippets),
+ LoadGolden("GenerateTestUndetectable.golden")));
+}
+
TEST(AssignmentsInBinaryExpression) {
InitializedIgnitionHandleScope scope;
BytecodeExpectationsPrinter printer(CcTest::isolate());
@@ -2121,6 +2169,9 @@ TEST(ClassDeclarations) {
"var count = 0;\n"
"class C { constructor() { count++; }}\n"
"return new C();\n",
+
+ "(class {})\n"
+ "class E { static name () {}}\n",
};
CHECK(CompareTexts(BuildActual(printer, snippets),
@@ -2250,6 +2301,48 @@ TEST(Modules) {
LoadGolden("Modules.golden")));
}
+TEST(SuperCallAndSpread) {
+ InitializedIgnitionHandleScope scope;
+ BytecodeExpectationsPrinter printer(CcTest::isolate());
+ printer.set_wrap(false);
+ printer.set_test_function_name("test");
+ const char* snippets[] = {
+ "var test;\n"
+ "(function() {\n"
+ " class A {\n"
+ " constructor(...args) { this.baseArgs = args; }\n"
+ " }\n"
+ " class B extends A {}\n"
+ " test = new B(1, 2, 3).constructor;\n"
+ "})();\n",
+
+ "var test;\n"
+ "(function() {\n"
+ " class A {\n"
+ " constructor(...args) { this.baseArgs = args; }\n"
+ " }\n"
+ " class B extends A {\n"
+ " constructor(...args) { super(1, ...args); }\n"
+ " }\n"
+ " test = new B(1, 2, 3).constructor;\n"
+ "})();\n",
+
+ "var test;\n"
+ "(function() {\n"
+ " class A {\n"
+ " constructor(...args) { this.baseArgs = args; }\n"
+ " }\n"
+ " class B extends A {\n"
+ " constructor(...args) { super(1, ...args, 1); }\n"
+ " }\n"
+ " test = new B(1, 2, 3).constructor;\n"
+ "})();\n",
+ };
+
+ CHECK(CompareTexts(BuildActual(printer, snippets),
+ LoadGolden("SuperCallAndSpread.golden")));
+}
+
} // namespace interpreter
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/cctest/interpreter/test-interpreter-intrinsics.cc b/deps/v8/test/cctest/interpreter/test-interpreter-intrinsics.cc
index 3cb2beffd4..70051253cc 100644
--- a/deps/v8/test/cctest/interpreter/test-interpreter-intrinsics.cc
+++ b/deps/v8/test/cctest/interpreter/test-interpreter-intrinsics.cc
@@ -114,27 +114,6 @@ TEST(IsJSProxy) {
*helper.Invoke(helper.NewObject("new Proxy({},{})")));
}
-TEST(IsRegExp) {
- HandleAndZoneScope handles;
-
- InvokeIntrinsicHelper helper(handles.main_isolate(), handles.main_zone(),
- Runtime::kInlineIsRegExp);
- Factory* factory = handles.main_isolate()->factory();
-
- CHECK_EQ(*factory->false_value(),
- *helper.Invoke(helper.NewObject("new Date()")));
- CHECK_EQ(*factory->false_value(),
- *helper.Invoke(helper.NewObject("(function() {})")));
- CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("([1])")));
- CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("({})")));
- CHECK_EQ(*factory->true_value(), *helper.Invoke(helper.NewObject("(/x/)")));
- CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.Undefined()));
- CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.Null()));
- CHECK_EQ(*factory->false_value(),
- *helper.Invoke(helper.NewObject("'string'")));
- CHECK_EQ(*factory->false_value(), *helper.Invoke(helper.NewObject("42")));
-}
-
TEST(IsTypedArray) {
HandleAndZoneScope handles;
diff --git a/deps/v8/test/cctest/interpreter/test-interpreter.cc b/deps/v8/test/cctest/interpreter/test-interpreter.cc
index f3f4021f88..ad2577aeab 100644
--- a/deps/v8/test/cctest/interpreter/test-interpreter.cc
+++ b/deps/v8/test/cctest/interpreter/test-interpreter.cc
@@ -12,6 +12,8 @@
#include "src/interpreter/bytecode-array-iterator.h"
#include "src/interpreter/bytecode-label.h"
#include "src/interpreter/interpreter.h"
+#include "src/objects-inl.h"
+#include "src/unicode-cache.h"
#include "test/cctest/cctest.h"
#include "test/cctest/interpreter/interpreter-tester.h"
#include "test/cctest/test-feedback-vector.h"
@@ -555,6 +557,10 @@ TEST(InterpreterBinaryOpTypeFeedback) {
isolate->factory()->NewHeapNumber(1.4142),
isolate->factory()->NewHeapNumber(3.1415 + 1.4142),
BinaryOperationFeedback::kNumber},
+ {Token::Value::ADD, isolate->factory()->NewStringFromAsciiChecked("foo"),
+ isolate->factory()->NewStringFromAsciiChecked("bar"),
+ isolate->factory()->NewStringFromAsciiChecked("foobar"),
+ BinaryOperationFeedback::kString},
{Token::Value::ADD, Handle<Smi>(Smi::FromInt(2), isolate),
isolate->factory()->NewStringFromAsciiChecked("2"),
isolate->factory()->NewStringFromAsciiChecked("22"),
@@ -1794,9 +1800,9 @@ TEST(InterpreterStringComparisons) {
BytecodeArrayBuilder builder(isolate, handles.main_zone(), 0, 0, 1);
Register r0(0);
- builder.LoadLiteral(factory->NewStringFromAsciiChecked(lhs))
+ builder.LoadLiteral(factory->InternalizeUtf8String(lhs))
.StoreAccumulatorInRegister(r0)
- .LoadLiteral(factory->NewStringFromAsciiChecked(rhs))
+ .LoadLiteral(factory->InternalizeUtf8String(rhs))
.CompareOperation(comparison, r0, vector->GetIndex(slot))
.Return();
@@ -1809,8 +1815,11 @@ TEST(InterpreterStringComparisons) {
CompareC(comparison, inputs[i], inputs[j]));
Object* feedback = vector->Get(slot);
CHECK(feedback->IsSmi());
- CHECK_EQ(CompareOperationFeedback::kAny,
- static_cast<Smi*>(feedback)->value());
+ int const expected_feedback =
+ Token::IsOrderedRelationalCompareOp(comparison)
+ ? CompareOperationFeedback::kString
+ : CompareOperationFeedback::kInternalizedString;
+ CHECK_EQ(expected_feedback, static_cast<Smi*>(feedback)->value());
}
}
}
@@ -1822,7 +1831,7 @@ TEST(InterpreterMixedComparisons) {
// convertible to a HeapNumber so comparison will be between numeric
// values except for the strict comparisons where no conversion is
// performed.
- const char* inputs[] = {"-1.77", "-40.333", "0.01", "55.77e5", "2.01"};
+ const char* inputs[] = {"-1.77", "-40.333", "0.01", "55.77e50", "2.01"};
UnicodeCache unicode_cache;
@@ -1875,8 +1884,10 @@ TEST(InterpreterMixedComparisons) {
CompareC(comparison, lhs, rhs, true));
Object* feedback = vector->Get(slot);
CHECK(feedback->IsSmi());
- CHECK_EQ(CompareOperationFeedback::kAny,
- static_cast<Smi*>(feedback)->value());
+ // kNumber | kString gets converted to CompareOperationHint::kAny.
+ int expected_feedback = CompareOperationFeedback::kNumber |
+ CompareOperationFeedback::kString;
+ CHECK_EQ(expected_feedback, static_cast<Smi*>(feedback)->value());
}
}
}
diff --git a/deps/v8/test/cctest/interpreter/test-source-positions.cc b/deps/v8/test/cctest/interpreter/test-source-positions.cc
index 2b7f5c368a..22fd4991ac 100644
--- a/deps/v8/test/cctest/interpreter/test-source-positions.cc
+++ b/deps/v8/test/cctest/interpreter/test-source-positions.cc
@@ -9,6 +9,7 @@
#include "src/interpreter/bytecode-generator.h"
#include "src/interpreter/interpreter.h"
#include "src/isolate.h"
+#include "src/objects-inl.h"
#include "test/cctest/cctest.h"
#include "test/cctest/interpreter/source-position-matcher.h"
@@ -226,9 +227,6 @@ bool OptimizedBytecodeSourcePositionTester::SourcePositionsMatch(
void TestSourcePositionsEquivalent(int optimization_bitmap) {
HandleAndZoneScope handles;
- // Ensure handler table is generated.
- handles.main_isolate()->interpreter()->Initialize();
-
OptimizedBytecodeSourcePositionTester tester(handles.main_isolate());
for (auto test_case_data : kTestCaseData) {
CHECK(tester.SourcePositionsMatch(
diff --git a/deps/v8/test/cctest/libplatform/test-tracing.cc b/deps/v8/test/cctest/libplatform/test-tracing.cc
index 6189ed2dfc..5dc6b965f1 100644
--- a/deps/v8/test/cctest/libplatform/test-tracing.cc
+++ b/deps/v8/test/cctest/libplatform/test-tracing.cc
@@ -25,6 +25,14 @@ TEST(TestTraceConfig) {
CHECK_EQ(trace_config->IsCategoryGroupEnabled(
TRACE_DISABLED_BY_DEFAULT("v8.runtime")),
true);
+ CHECK_EQ(trace_config->IsCategoryGroupEnabled("v8,v8.cpu_profile"), true);
+ CHECK_EQ(
+ trace_config->IsCategoryGroupEnabled("v8,disabled-by-default-v8.runtime"),
+ true);
+ CHECK_EQ(trace_config->IsCategoryGroupEnabled(
+ "v8_cpu_profile,v8.cpu_profile.hires"),
+ false);
+
delete trace_config;
}
diff --git a/deps/v8/test/cctest/parsing/test-parse-decision.cc b/deps/v8/test/cctest/parsing/test-parse-decision.cc
new file mode 100644
index 0000000000..f91bd57739
--- /dev/null
+++ b/deps/v8/test/cctest/parsing/test-parse-decision.cc
@@ -0,0 +1,107 @@
+// 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.
+
+// Test specific cases of the lazy/eager-parse decision.
+//
+// Note that presently most unit tests for parsing are found in
+// cctest/test-parsing.cc.
+
+#include <unordered_map>
+
+#include "include/v8.h"
+#include "src/api.h"
+#include "src/handles-inl.h"
+#include "src/isolate.h"
+#include "src/objects-inl.h"
+#include "src/utils.h"
+
+#include "test/cctest/cctest.h"
+
+using namespace v8::internal;
+
+namespace {
+
+// Record the 'compiled' state of all top level functions.
+void GetTopLevelFunctionInfo(
+ v8::Local<v8::Script> script,
+ std::unordered_map<std::string, bool>* is_compiled) {
+ // Get the v8::internal::Script object from the API v8::Script.
+ // The API object 'wraps' the compiled top-level function, not the i::Script.
+ Handle<JSFunction> toplevel_fn = v8::Utils::OpenHandle(*script);
+ Handle<Script> i_script =
+ handle(Script::cast(toplevel_fn->shared()->script()));
+ SharedFunctionInfo::ScriptIterator iterator(i_script);
+
+ while (SharedFunctionInfo* shared = iterator.Next()) {
+ std::unique_ptr<char[]> name = String::cast(shared->name())->ToCString();
+ is_compiled->insert(std::make_pair(name.get(), shared->is_compiled()));
+ }
+}
+
+} // anonymous namespace
+
+TEST(GetTopLevelFunctionInfo) {
+ if (!FLAG_lazy) return;
+
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ LocalContext env;
+
+ const char src[] = "function foo() { var a; }\n";
+ std::unordered_map<std::string, bool> is_compiled;
+ GetTopLevelFunctionInfo(v8_compile(src), &is_compiled);
+
+ // Test that our helper function GetTopLevelFunctionInfo does what it claims:
+ DCHECK(is_compiled.find("foo") != is_compiled.end());
+ DCHECK(is_compiled.find("bar") == is_compiled.end());
+}
+
+TEST(EagerlyCompileImmediateUseFunctions) {
+ if (!FLAG_lazy) return;
+
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ LocalContext env;
+
+ // Test parenthesized, exclaimed, and regular functions. Make sure these
+ // occur both intermixed and after each other, to make sure the 'reset'
+ // mechanism works.
+ const char src[] =
+ "function normal() { var a; }\n" // Normal: Should lazy parse.
+ "(function parenthesized() { var b; })()\n" // Parenthesized: Pre-parse.
+ "!function exclaimed() { var c; }() \n" // Exclaimed: Pre-parse.
+ "function normal2() { var d; }\n"
+ "(function parenthesized2() { var e; })()\n"
+ "function normal3() { var f; }\n"
+ "!function exclaimed2() { var g; }() \n"
+ "function normal4() { var h; }\n";
+
+ std::unordered_map<std::string, bool> is_compiled;
+ GetTopLevelFunctionInfo(v8_compile(src), &is_compiled);
+
+ DCHECK(is_compiled["parenthesized"]);
+ DCHECK(is_compiled["parenthesized2"]);
+ DCHECK(is_compiled["exclaimed"]);
+ DCHECK(is_compiled["exclaimed2"]);
+ DCHECK(!is_compiled["normal"]);
+ DCHECK(!is_compiled["normal2"]);
+ DCHECK(!is_compiled["normal3"]);
+ DCHECK(!is_compiled["normal4"]);
+}
+
+TEST(CommaFunctionSequence) {
+ if (!FLAG_lazy) return;
+
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ LocalContext env;
+
+ const char src[] = "!function a(){}(),function b(){}(),function c(){}();";
+ std::unordered_map<std::string, bool> is_compiled;
+ GetTopLevelFunctionInfo(v8_compile(src), &is_compiled);
+
+ DCHECK(is_compiled["a"]);
+ DCHECK(is_compiled["b"]);
+ DCHECK(is_compiled["c"]);
+}
diff --git a/deps/v8/test/cctest/parsing/test-scanner-streams.cc b/deps/v8/test/cctest/parsing/test-scanner-streams.cc
index 3f5ae50d45..b4b28f1fc5 100644
--- a/deps/v8/test/cctest/parsing/test-scanner-streams.cc
+++ b/deps/v8/test/cctest/parsing/test-scanner-streams.cc
@@ -100,7 +100,7 @@ TEST(Utf8StreamAsciiOnly) {
ChunkSource chunk_source(chunks);
std::unique_ptr<v8::internal::Utf16CharacterStream> stream(
v8::internal::ScannerStream::For(
- &chunk_source, v8::ScriptCompiler::StreamedSource::UTF8));
+ &chunk_source, v8::ScriptCompiler::StreamedSource::UTF8, nullptr));
// Read the data without dying.
v8::internal::uc32 c;
@@ -118,7 +118,7 @@ TEST(Utf8StreamBOM) {
ChunkSource chunk_source(chunks);
std::unique_ptr<v8::internal::Utf16CharacterStream> stream(
v8::internal::ScannerStream::For(
- &chunk_source, v8::ScriptCompiler::StreamedSource::UTF8));
+ &chunk_source, v8::ScriptCompiler::StreamedSource::UTF8, nullptr));
// Read the data without tripping over the BOM.
for (size_t i = 0; unicode_ucs2[i]; i++) {
@@ -152,7 +152,7 @@ TEST(Utf8SplitBOM) {
ChunkSource chunk_source(chunks);
std::unique_ptr<v8::internal::Utf16CharacterStream> stream(
v8::internal::ScannerStream::For(
- &chunk_source, v8::ScriptCompiler::StreamedSource::UTF8));
+ &chunk_source, v8::ScriptCompiler::StreamedSource::UTF8, nullptr));
// Read the data without tripping over the BOM.
for (size_t i = 0; unicode_ucs2[i]; i++) {
@@ -168,7 +168,7 @@ TEST(Utf8SplitBOM) {
ChunkSource chunk_source(chunks);
std::unique_ptr<v8::internal::Utf16CharacterStream> stream(
v8::internal::ScannerStream::For(
- &chunk_source, v8::ScriptCompiler::StreamedSource::UTF8));
+ &chunk_source, v8::ScriptCompiler::StreamedSource::UTF8, nullptr));
// Read the data without tripping over the BOM.
for (size_t i = 0; unicode_ucs2[i]; i++) {
@@ -197,7 +197,7 @@ TEST(Utf8ChunkBoundaries) {
ChunkSource chunk_source(chunks);
std::unique_ptr<v8::internal::Utf16CharacterStream> stream(
v8::internal::ScannerStream::For(
- &chunk_source, v8::ScriptCompiler::StreamedSource::UTF8));
+ &chunk_source, v8::ScriptCompiler::StreamedSource::UTF8, nullptr));
for (size_t i = 0; unicode_ucs2[i]; i++) {
CHECK_EQ(unicode_ucs2[i], stream->Advance());
@@ -226,7 +226,7 @@ TEST(Utf8SingleByteChunks) {
ChunkSource chunk_source(chunks);
std::unique_ptr<v8::internal::Utf16CharacterStream> stream(
v8::internal::ScannerStream::For(
- &chunk_source, v8::ScriptCompiler::StreamedSource::UTF8));
+ &chunk_source, v8::ScriptCompiler::StreamedSource::UTF8, nullptr));
for (size_t j = 0; unicode_ucs2[j]; j++) {
CHECK_EQ(unicode_ucs2[j], stream->Advance());
@@ -358,13 +358,14 @@ void TestCharacterStreams(const char* one_byte_source, unsigned length,
ChunkSource single_chunk(data, data_end - data, false);
std::unique_ptr<i::Utf16CharacterStream> one_byte_streaming_stream(
i::ScannerStream::For(&single_chunk,
- v8::ScriptCompiler::StreamedSource::ONE_BYTE));
+ v8::ScriptCompiler::StreamedSource::ONE_BYTE,
+ nullptr));
TestCharacterStream(one_byte_source, one_byte_streaming_stream.get(),
length, start, end);
ChunkSource many_chunks(data, data_end - data, true);
one_byte_streaming_stream.reset(i::ScannerStream::For(
- &many_chunks, v8::ScriptCompiler::StreamedSource::ONE_BYTE));
+ &many_chunks, v8::ScriptCompiler::StreamedSource::ONE_BYTE, nullptr));
TestCharacterStream(one_byte_source, one_byte_streaming_stream.get(),
length, start, end);
}
@@ -377,14 +378,14 @@ void TestCharacterStreams(const char* one_byte_source, unsigned length,
reinterpret_cast<const uint8_t*>(one_byte_vector.end());
ChunkSource chunks(data, data_end - data, false);
std::unique_ptr<i::Utf16CharacterStream> utf8_streaming_stream(
- i::ScannerStream::For(&chunks,
- v8::ScriptCompiler::StreamedSource::UTF8));
+ i::ScannerStream::For(&chunks, v8::ScriptCompiler::StreamedSource::UTF8,
+ nullptr));
TestCharacterStream(one_byte_source, utf8_streaming_stream.get(), length,
start, end);
ChunkSource many_chunks(data, data_end - data, true);
utf8_streaming_stream.reset(i::ScannerStream::For(
- &many_chunks, v8::ScriptCompiler::StreamedSource::UTF8));
+ &many_chunks, v8::ScriptCompiler::StreamedSource::UTF8, nullptr));
TestCharacterStream(one_byte_source, utf8_streaming_stream.get(), length,
start, end);
}
@@ -397,14 +398,14 @@ void TestCharacterStreams(const char* one_byte_source, unsigned length,
reinterpret_cast<const uint8_t*>(two_byte_vector.end());
ChunkSource chunks(data, data_end - data, false);
std::unique_ptr<i::Utf16CharacterStream> two_byte_streaming_stream(
- i::ScannerStream::For(&chunks,
- v8::ScriptCompiler::StreamedSource::TWO_BYTE));
+ i::ScannerStream::For(
+ &chunks, v8::ScriptCompiler::StreamedSource::TWO_BYTE, nullptr));
TestCharacterStream(one_byte_source, two_byte_streaming_stream.get(),
length, start, end);
ChunkSource many_chunks(data, data_end - data, true);
two_byte_streaming_stream.reset(i::ScannerStream::For(
- &many_chunks, v8::ScriptCompiler::StreamedSource::TWO_BYTE));
+ &many_chunks, v8::ScriptCompiler::StreamedSource::TWO_BYTE, nullptr));
TestCharacterStream(one_byte_source, two_byte_streaming_stream.get(),
length, start, end);
}
@@ -446,7 +447,7 @@ TEST(Regress651333) {
// 65533) instead of the incorrectly coded Latin1 char.
ChunkSource chunks(bytes, len, false);
std::unique_ptr<i::Utf16CharacterStream> stream(i::ScannerStream::For(
- &chunks, v8::ScriptCompiler::StreamedSource::UTF8));
+ &chunks, v8::ScriptCompiler::StreamedSource::UTF8, nullptr));
for (size_t i = 0; i < len; i++) {
CHECK_EQ(unicode[i], stream->Advance());
}
diff --git a/deps/v8/test/cctest/parsing/test-scanner.cc b/deps/v8/test/cctest/parsing/test-scanner.cc
index 12884ba106..0577d713fa 100644
--- a/deps/v8/test/cctest/parsing/test-scanner.cc
+++ b/deps/v8/test/cctest/parsing/test-scanner.cc
@@ -6,6 +6,7 @@
// Scanner are in cctest/test-parsing.cc, rather than here.
#include "src/handles-inl.h"
+#include "src/objects-inl.h"
#include "src/parsing/scanner-character-streams.h"
#include "src/parsing/scanner.h"
#include "src/unicode-cache.h"
@@ -17,10 +18,29 @@ namespace {
const char src_simple[] = "function foo() { var x = 2 * a() + b; }";
-std::unique_ptr<Scanner> make_scanner(const char* src, UnicodeCache* cache) {
- std::unique_ptr<Scanner> scanner(new Scanner(cache));
- scanner->Initialize(ScannerStream::ForTesting(src).release());
- return scanner;
+struct ScannerTestHelper {
+ ScannerTestHelper() = default;
+ ScannerTestHelper(ScannerTestHelper&& other)
+ : unicode_cache(std::move(other.unicode_cache)),
+ stream(std::move(other.stream)),
+ scanner(std::move(other.scanner)) {}
+
+ std::unique_ptr<UnicodeCache> unicode_cache;
+ std::unique_ptr<Utf16CharacterStream> stream;
+ std::unique_ptr<Scanner> scanner;
+
+ Scanner* operator->() const { return scanner.get(); }
+ Scanner* get() const { return scanner.get(); }
+};
+
+ScannerTestHelper make_scanner(const char* src) {
+ ScannerTestHelper helper;
+ helper.unicode_cache = std::unique_ptr<UnicodeCache>(new UnicodeCache);
+ helper.stream = ScannerStream::ForTesting(src);
+ helper.scanner =
+ std::unique_ptr<Scanner>(new Scanner(helper.unicode_cache.get()));
+ helper.scanner->Initialize(helper.stream.get());
+ return helper;
}
} // anonymous namespace
@@ -30,13 +50,11 @@ std::unique_ptr<Scanner> make_scanner(const char* src, UnicodeCache* cache) {
#define DCHECK_TOK(a, b) DCHECK_EQ(Token::Name(a), Token::Name(b))
TEST(Bookmarks) {
- UnicodeCache unicode_cache;
-
// Scan through the given source and record the tokens for use as reference
// below.
std::vector<Token::Value> tokens;
{
- auto scanner = make_scanner(src_simple, &unicode_cache);
+ auto scanner = make_scanner(src_simple);
do {
tokens.push_back(scanner->Next());
} while (scanner->current_token() != Token::EOS);
@@ -50,7 +68,7 @@ TEST(Bookmarks) {
// - scan until the end.
// At each step, compare to the reference token sequence generated above.
for (size_t bookmark_pos = 0; bookmark_pos < tokens.size(); bookmark_pos++) {
- auto scanner = make_scanner(src_simple, &unicode_cache);
+ auto scanner = make_scanner(src_simple);
Scanner::BookmarkScope bookmark(scanner.get());
for (size_t i = 0; i < std::min(bookmark_pos + 10, tokens.size()); i++) {
@@ -79,9 +97,8 @@ TEST(AllThePushbacks) {
{"<!-- xx -->\nx", {Token::IDENTIFIER, Token::EOS}},
};
- UnicodeCache unicode_cache;
for (const auto& test_case : test_cases) {
- auto scanner = make_scanner(test_case.src, &unicode_cache);
+ auto scanner = make_scanner(test_case.src);
for (size_t i = 0; test_case.tokens[i] != Token::EOS; i++) {
DCHECK_TOK(test_case.tokens[i], scanner->Next());
}
diff --git a/deps/v8/test/cctest/test-access-checks.cc b/deps/v8/test/cctest/test-access-checks.cc
index 59c17b89eb..727444b532 100644
--- a/deps/v8/test/cctest/test-access-checks.cc
+++ b/deps/v8/test/cctest/test-access-checks.cc
@@ -102,6 +102,29 @@ void IndexedEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info) {
info.GetReturnValue().Set(names);
}
+void NamedGetterThrowsException(
+ v8::Local<v8::Name> property,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ info.GetIsolate()->ThrowException(v8_str("exception"));
+}
+
+void NamedSetterThrowsException(
+ v8::Local<v8::Name> property, v8::Local<v8::Value> value,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ info.GetIsolate()->ThrowException(v8_str("exception"));
+}
+
+void IndexedGetterThrowsException(
+ uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info) {
+ info.GetIsolate()->ThrowException(v8_str("exception"));
+}
+
+void IndexedSetterThrowsException(
+ uint32_t index, v8::Local<v8::Value> value,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ info.GetIsolate()->ThrowException(v8_str("exception"));
+}
+
bool AccessCheck(v8::Local<v8::Context> accessing_context,
v8::Local<v8::Object> accessed_object,
v8::Local<v8::Value> data) {
@@ -181,6 +204,56 @@ void CheckCrossContextAccess(v8::Isolate* isolate,
"[\"7\",\"cross_context_int\"]");
}
+void CheckCrossContextAccessWithException(
+ v8::Isolate* isolate, v8::Local<v8::Context> accessing_context,
+ v8::Local<v8::Object> accessed_object) {
+ v8::HandleScope handle_scope(isolate);
+ accessing_context->Global()
+ ->Set(accessing_context, v8_str("other"), accessed_object)
+ .FromJust();
+ v8::Context::Scope context_scope(accessing_context);
+
+ {
+ v8::TryCatch try_catch(isolate);
+ CompileRun("this.other.should_throw");
+ CHECK(try_catch.HasCaught());
+ CHECK(try_catch.Exception()->IsString());
+ CHECK(v8_str("exception")
+ ->Equals(accessing_context, try_catch.Exception())
+ .FromJust());
+ }
+
+ {
+ v8::TryCatch try_catch(isolate);
+ CompileRun("this.other.should_throw = 8");
+ CHECK(try_catch.HasCaught());
+ CHECK(try_catch.Exception()->IsString());
+ CHECK(v8_str("exception")
+ ->Equals(accessing_context, try_catch.Exception())
+ .FromJust());
+ }
+
+ {
+ v8::TryCatch try_catch(isolate);
+ CompileRun("this.other[42]");
+ CHECK(try_catch.HasCaught());
+ CHECK(try_catch.Exception()->IsString());
+ CHECK(v8_str("exception")
+ ->Equals(accessing_context, try_catch.Exception())
+ .FromJust());
+ }
+
+ {
+ v8::TryCatch try_catch(isolate);
+ CompileRun("this.other[42] = 8");
+ CHECK(try_catch.HasCaught());
+ CHECK(try_catch.Exception()->IsString());
+ CHECK(v8_str("exception")
+ ->Equals(accessing_context, try_catch.Exception())
+ .FromJust());
+ }
+}
+
void Ctor(const v8::FunctionCallbackInfo<v8::Value>& info) {
CHECK(info.IsConstructCall());
}
@@ -215,6 +288,32 @@ TEST(AccessCheckWithInterceptor) {
CheckCrossContextAccess(isolate, context1, context0->Global());
}
+TEST(AccessCheckWithExceptionThrowingInterceptor) {
+ v8::Isolate* isolate = CcTest::isolate();
+ isolate->SetFailedAccessCheckCallbackFunction([](v8::Local<v8::Object> target,
+ v8::AccessType type,
+ v8::Local<v8::Value> data) {
+ CHECK(false); // This should never be called.
+ });
+
+ v8::HandleScope scope(isolate);
+ v8::Local<v8::ObjectTemplate> global_template =
+ v8::ObjectTemplate::New(isolate);
+ global_template->SetAccessCheckCallbackAndHandler(
+ AccessCheck, v8::NamedPropertyHandlerConfiguration(
+ NamedGetterThrowsException, NamedSetterThrowsException),
+ v8::IndexedPropertyHandlerConfiguration(IndexedGetterThrowsException,
+ IndexedSetterThrowsException));
+
+ // Create two contexts.
+ v8::Local<v8::Context> context0 =
+ v8::Context::New(isolate, nullptr, global_template);
+ v8::Local<v8::Context> context1 =
+ v8::Context::New(isolate, nullptr, global_template);
+
+ CheckCrossContextAccessWithException(isolate, context1, context0->Global());
+}
+
TEST(NewRemoteContext) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
diff --git a/deps/v8/test/cctest/test-accessor-assembler.cc b/deps/v8/test/cctest/test-accessor-assembler.cc
new file mode 100644
index 0000000000..c129bbaf13
--- /dev/null
+++ b/deps/v8/test/cctest/test-accessor-assembler.cc
@@ -0,0 +1,263 @@
+// 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 "test/cctest/cctest.h"
+
+#include "src/base/utils/random-number-generator.h"
+#include "src/ic/accessor-assembler-impl.h"
+#include "src/ic/stub-cache.h"
+#include "test/cctest/compiler/code-assembler-tester.h"
+#include "test/cctest/compiler/function-tester.h"
+
+namespace v8 {
+namespace internal {
+
+using compiler::CodeAssemblerTester;
+using compiler::FunctionTester;
+using compiler::Node;
+
+namespace {
+
+void TestStubCacheOffsetCalculation(StubCache::Table table) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+ const int kNumParams = 2;
+ CodeAssemblerTester data(isolate, kNumParams);
+ AccessorAssemblerImpl m(data.state());
+
+ {
+ Node* name = m.Parameter(0);
+ Node* map = m.Parameter(1);
+ Node* primary_offset = m.StubCachePrimaryOffsetForTesting(name, map);
+ Node* result;
+ if (table == StubCache::kPrimary) {
+ result = primary_offset;
+ } else {
+ CHECK_EQ(StubCache::kSecondary, table);
+ result = m.StubCacheSecondaryOffsetForTesting(name, primary_offset);
+ }
+ m.Return(m.SmiTag(result));
+ }
+
+ Handle<Code> code = data.GenerateCode();
+ FunctionTester ft(code, kNumParams);
+
+ Factory* factory = isolate->factory();
+ Handle<Name> names[] = {
+ factory->NewSymbol(),
+ factory->InternalizeUtf8String("a"),
+ factory->InternalizeUtf8String("bb"),
+ factory->InternalizeUtf8String("ccc"),
+ factory->NewPrivateSymbol(),
+ factory->InternalizeUtf8String("dddd"),
+ factory->InternalizeUtf8String("eeeee"),
+ factory->InternalizeUtf8String("name"),
+ factory->NewSymbol(),
+ factory->NewPrivateSymbol(),
+ };
+
+ Handle<Map> maps[] = {
+ Handle<Map>(nullptr, isolate),
+ factory->cell_map(),
+ Map::Create(isolate, 0),
+ factory->meta_map(),
+ factory->code_map(),
+ Map::Create(isolate, 0),
+ factory->hash_table_map(),
+ factory->symbol_map(),
+ factory->string_map(),
+ Map::Create(isolate, 0),
+ factory->sloppy_arguments_elements_map(),
+ };
+
+ for (size_t name_index = 0; name_index < arraysize(names); name_index++) {
+ Handle<Name> name = names[name_index];
+ for (size_t map_index = 0; map_index < arraysize(maps); map_index++) {
+ Handle<Map> map = maps[map_index];
+
+ int expected_result;
+ {
+ int primary_offset = StubCache::PrimaryOffsetForTesting(*name, *map);
+ if (table == StubCache::kPrimary) {
+ expected_result = primary_offset;
+ } else {
+ expected_result =
+ StubCache::SecondaryOffsetForTesting(*name, primary_offset);
+ }
+ }
+ Handle<Object> result = ft.Call(name, map).ToHandleChecked();
+
+ Smi* expected = Smi::FromInt(expected_result & Smi::kMaxValue);
+ CHECK_EQ(expected, Smi::cast(*result));
+ }
+ }
+}
+
+} // namespace
+
+TEST(StubCachePrimaryOffset) {
+ TestStubCacheOffsetCalculation(StubCache::kPrimary);
+}
+
+TEST(StubCacheSecondaryOffset) {
+ TestStubCacheOffsetCalculation(StubCache::kSecondary);
+}
+
+namespace {
+
+Handle<Code> CreateCodeWithFlags(Code::Flags flags) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+ CodeAssemblerTester data(isolate, flags);
+ CodeStubAssembler m(data.state());
+ m.Return(m.UndefinedConstant());
+ return data.GenerateCodeCloseAndEscape();
+}
+
+} // namespace
+
+TEST(TryProbeStubCache) {
+ typedef CodeStubAssembler::Label Label;
+ typedef CodeStubAssembler::Variable Variable;
+ Isolate* isolate(CcTest::InitIsolateOnce());
+ const int kNumParams = 3;
+ CodeAssemblerTester data(isolate, kNumParams);
+ AccessorAssemblerImpl m(data.state());
+
+ Code::Kind ic_kind = Code::LOAD_IC;
+ StubCache stub_cache(isolate, ic_kind);
+ stub_cache.Clear();
+
+ {
+ Node* receiver = m.Parameter(0);
+ Node* name = m.Parameter(1);
+ Node* expected_handler = m.Parameter(2);
+
+ Label passed(&m), failed(&m);
+
+ Variable var_handler(&m, MachineRepresentation::kTagged);
+ Label if_handler(&m), if_miss(&m);
+
+ m.TryProbeStubCache(&stub_cache, receiver, name, &if_handler, &var_handler,
+ &if_miss);
+ m.Bind(&if_handler);
+ m.Branch(m.WordEqual(expected_handler, var_handler.value()), &passed,
+ &failed);
+
+ m.Bind(&if_miss);
+ m.Branch(m.WordEqual(expected_handler, m.IntPtrConstant(0)), &passed,
+ &failed);
+
+ m.Bind(&passed);
+ m.Return(m.BooleanConstant(true));
+
+ m.Bind(&failed);
+ m.Return(m.BooleanConstant(false));
+ }
+
+ Handle<Code> code = data.GenerateCode();
+ FunctionTester ft(code, kNumParams);
+
+ std::vector<Handle<Name>> names;
+ std::vector<Handle<JSObject>> receivers;
+ std::vector<Handle<Code>> handlers;
+
+ base::RandomNumberGenerator rand_gen(FLAG_random_seed);
+
+ Factory* factory = isolate->factory();
+
+ // Generate some number of names.
+ for (int i = 0; i < StubCache::kPrimaryTableSize / 7; i++) {
+ Handle<Name> name;
+ switch (rand_gen.NextInt(3)) {
+ case 0: {
+ // Generate string.
+ std::stringstream ss;
+ ss << "s" << std::hex
+ << (rand_gen.NextInt(Smi::kMaxValue) % StubCache::kPrimaryTableSize);
+ name = factory->InternalizeUtf8String(ss.str().c_str());
+ break;
+ }
+ case 1: {
+ // Generate number string.
+ std::stringstream ss;
+ ss << (rand_gen.NextInt(Smi::kMaxValue) % StubCache::kPrimaryTableSize);
+ name = factory->InternalizeUtf8String(ss.str().c_str());
+ break;
+ }
+ case 2: {
+ // Generate symbol.
+ name = factory->NewSymbol();
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+ names.push_back(name);
+ }
+
+ // Generate some number of receiver maps and receivers.
+ for (int i = 0; i < StubCache::kSecondaryTableSize / 2; i++) {
+ Handle<Map> map = Map::Create(isolate, 0);
+ receivers.push_back(factory->NewJSObjectFromMap(map));
+ }
+
+ // Generate some number of handlers.
+ for (int i = 0; i < 30; i++) {
+ Code::Flags flags =
+ Code::RemoveHolderFromFlags(Code::ComputeHandlerFlags(ic_kind));
+ handlers.push_back(CreateCodeWithFlags(flags));
+ }
+
+ // Ensure that GC does happen because from now on we are going to fill our
+ // own stub cache instance with raw values.
+ DisallowHeapAllocation no_gc;
+
+ // Populate {stub_cache}.
+ const int N = StubCache::kPrimaryTableSize + StubCache::kSecondaryTableSize;
+ for (int i = 0; i < N; i++) {
+ int index = rand_gen.NextInt();
+ Handle<Name> name = names[index % names.size()];
+ Handle<JSObject> receiver = receivers[index % receivers.size()];
+ Handle<Code> handler = handlers[index % handlers.size()];
+ stub_cache.Set(*name, receiver->map(), *handler);
+ }
+
+ // Perform some queries.
+ bool queried_existing = false;
+ bool queried_non_existing = false;
+ for (int i = 0; i < N; i++) {
+ int index = rand_gen.NextInt();
+ Handle<Name> name = names[index % names.size()];
+ Handle<JSObject> receiver = receivers[index % receivers.size()];
+ Object* handler = stub_cache.Get(*name, receiver->map());
+ if (handler == nullptr) {
+ queried_non_existing = true;
+ } else {
+ queried_existing = true;
+ }
+
+ Handle<Object> expected_handler(handler, isolate);
+ ft.CheckTrue(receiver, name, expected_handler);
+ }
+
+ for (int i = 0; i < N; i++) {
+ int index1 = rand_gen.NextInt();
+ int index2 = rand_gen.NextInt();
+ Handle<Name> name = names[index1 % names.size()];
+ Handle<JSObject> receiver = receivers[index2 % receivers.size()];
+ Object* handler = stub_cache.Get(*name, receiver->map());
+ if (handler == nullptr) {
+ queried_non_existing = true;
+ } else {
+ queried_existing = true;
+ }
+
+ Handle<Object> expected_handler(handler, isolate);
+ ft.CheckTrue(receiver, name, expected_handler);
+ }
+ // Ensure we performed both kind of queries.
+ CHECK(queried_existing && queried_non_existing);
+}
+
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/cctest/test-api-accessors.cc b/deps/v8/test/cctest/test-api-accessors.cc
index e9773e918d..cc0c7efb5f 100644
--- a/deps/v8/test/cctest/test-api-accessors.cc
+++ b/deps/v8/test/cctest/test-api-accessors.cc
@@ -7,6 +7,7 @@
#include "include/v8-experimental.h"
#include "include/v8.h"
#include "src/api.h"
+#include "src/objects-inl.h"
namespace i = v8::internal;
@@ -247,3 +248,33 @@ TEST(CachedAccessorCrankshaft) {
ExpectInt32("g()", 789);
}
+
+namespace {
+
+static void Setter(v8::Local<v8::String> name, v8::Local<v8::Value> value,
+ const v8::PropertyCallbackInfo<void>& info) {}
+}
+
+// Re-declaration of non-configurable accessors should throw.
+TEST(RedeclareAccessor) {
+ v8::HandleScope scope(CcTest::isolate());
+ LocalContext env;
+
+ v8::Local<v8::FunctionTemplate> templ =
+ v8::FunctionTemplate::New(CcTest::isolate());
+
+ v8::Local<v8::ObjectTemplate> object_template = templ->InstanceTemplate();
+ object_template->SetAccessor(
+ v8_str("foo"), NULL, Setter, v8::Local<v8::Value>(),
+ v8::AccessControl::DEFAULT, v8::PropertyAttribute::DontDelete);
+
+ v8::Local<v8::Context> ctx =
+ v8::Context::New(CcTest::isolate(), nullptr, object_template);
+
+ // Declare function.
+ v8::Local<v8::String> code = v8_str("function foo() {};");
+
+ v8::TryCatch try_catch(CcTest::isolate());
+ v8::Script::Compile(ctx, code).ToLocalChecked()->Run(ctx).IsEmpty();
+ CHECK(try_catch.HasCaught());
+}
diff --git a/deps/v8/test/cctest/test-api-fast-accessor-builder.cc b/deps/v8/test/cctest/test-api-fast-accessor-builder.cc
index 6612f9047c..8b85e2aa34 100644
--- a/deps/v8/test/cctest/test-api-fast-accessor-builder.cc
+++ b/deps/v8/test/cctest/test-api-fast-accessor-builder.cc
@@ -8,6 +8,7 @@
#include "include/v8-experimental.h"
#include "src/api.h"
+#include "src/objects-inl.h"
#include "test/cctest/cctest.h"
namespace {
diff --git a/deps/v8/test/cctest/test-api-interceptors.cc b/deps/v8/test/cctest/test-api-interceptors.cc
index 396efca01d..6aebba67bc 100644
--- a/deps/v8/test/cctest/test-api-interceptors.cc
+++ b/deps/v8/test/cctest/test-api-interceptors.cc
@@ -380,11 +380,8 @@ void InterceptorHasOwnPropertyGetterGC(
CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
}
-} // namespace
-
int query_counter_int = 0;
-namespace {
void QueryCallback(Local<Name> property,
const v8::PropertyCallbackInfo<v8::Integer>& info) {
query_counter_int++;
@@ -479,12 +476,13 @@ THREADED_TEST(QueryInterceptor) {
CHECK_EQ(query_counter_int, 8);
}
+namespace {
+
bool get_was_called = false;
bool set_was_called = false;
int set_was_called_counter = 0;
-namespace {
void GetterCallback(Local<Name> property,
const v8::PropertyCallbackInfo<v8::Value>& info) {
get_was_called = true;
@@ -609,56 +607,13 @@ THREADED_TEST(SetterCallbackFunctionDeclarationInterceptorThrow) {
CHECK_EQ(set_was_called, false);
}
-namespace {
-int descriptor_was_called;
-void PropertyDescriptorCallback(
- Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
- // Intercept the callback by setting a different descriptor.
- descriptor_was_called++;
- const char* code =
- "var desc = {value: 5};"
- "desc;";
- Local<Value> descriptor = v8_compile(code)
- ->Run(info.GetIsolate()->GetCurrentContext())
- .ToLocalChecked();
- info.GetReturnValue().Set(descriptor);
-}
-} // namespace
-// Check that the descriptor callback is called on the global object.
-THREADED_TEST(DescriptorCallbackOnGlobalObject) {
- v8::HandleScope scope(CcTest::isolate());
- LocalContext env;
- v8::Local<v8::FunctionTemplate> templ =
- v8::FunctionTemplate::New(CcTest::isolate());
-
- v8::Local<ObjectTemplate> object_template = templ->InstanceTemplate();
- object_template->SetHandler(v8::NamedPropertyHandlerConfiguration(
- nullptr, nullptr, PropertyDescriptorCallback, nullptr, nullptr, nullptr));
- v8::Local<v8::Context> ctx =
- v8::Context::New(CcTest::isolate(), nullptr, object_template);
-
- descriptor_was_called = 0;
-
- // Declare function.
- v8::Local<v8::String> code = v8_str(
- "var x = 42; var desc = Object.getOwnPropertyDescriptor(this, 'x'); "
- "desc.value;");
- CHECK_EQ(5, v8::Script::Compile(ctx, code)
- .ToLocalChecked()
- ->Run(ctx)
- .ToLocalChecked()
- ->Int32Value(ctx)
- .FromJust());
- CHECK_EQ(1, descriptor_was_called);
-}
+namespace {
bool get_was_called_in_order = false;
bool define_was_called_in_order = false;
-namespace {
-
void GetterCallbackOrder(Local<Name> property,
const v8::PropertyCallbackInfo<v8::Value>& info) {
get_was_called_in_order = true;
@@ -700,6 +655,68 @@ THREADED_TEST(DefinerCallbackGetAndDefine) {
CHECK_EQ(define_was_called_in_order, true);
}
+namespace { // namespace for InObjectLiteralDefinitionWithInterceptor
+
+// Workaround for no-snapshot builds: only intercept once Context::New() is
+// done, otherwise we'll intercept
+// bootstrapping like defining array on the global object.
+bool context_is_done = false;
+bool getter_callback_was_called = false;
+
+void ReturnUndefinedGetterCallback(
+ Local<Name> property, const v8::PropertyCallbackInfo<v8::Value>& info) {
+ if (context_is_done) {
+ getter_callback_was_called = true;
+ info.GetReturnValue().SetUndefined();
+ }
+}
+
+} // namespace
+
+// Check that an interceptor is not invoked during ES6 style definitions inside
+// an object literal.
+THREADED_TEST(InObjectLiteralDefinitionWithInterceptor) {
+ v8::HandleScope scope(CcTest::isolate());
+ LocalContext env;
+
+ // Set up a context in which all global object definitions are intercepted.
+ v8::Local<v8::FunctionTemplate> templ =
+ v8::FunctionTemplate::New(CcTest::isolate());
+ v8::Local<ObjectTemplate> object_template = templ->InstanceTemplate();
+ object_template->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(ReturnUndefinedGetterCallback));
+ v8::Local<v8::Context> ctx =
+ v8::Context::New(CcTest::isolate(), nullptr, object_template);
+
+ context_is_done = true;
+
+ // The interceptor returns undefined for any global object,
+ // so setting a property on an object should throw.
+ v8::Local<v8::String> code = v8_str("var o = {}; o.x = 5");
+ {
+ getter_callback_was_called = false;
+ v8::TryCatch try_catch(CcTest::isolate());
+ CHECK(v8::Script::Compile(ctx, code).ToLocalChecked()->Run(ctx).IsEmpty());
+ CHECK(try_catch.HasCaught());
+ CHECK(getter_callback_was_called);
+ }
+
+ // Defining a property in the object literal should not throw
+ // because the interceptor is not invoked.
+ {
+ getter_callback_was_called = false;
+ v8::TryCatch try_catch(CcTest::isolate());
+ code = v8_str("var l = {x: 5};");
+ CHECK(v8::Script::Compile(ctx, code)
+ .ToLocalChecked()
+ ->Run(ctx)
+ .ToLocalChecked()
+ ->IsUndefined());
+ CHECK(!try_catch.HasCaught());
+ CHECK(!getter_callback_was_called);
+ }
+}
+
THREADED_TEST(InterceptorHasOwnProperty) {
LocalContext context;
v8::Isolate* isolate = context->GetIsolate();
@@ -1954,8 +1971,9 @@ THREADED_TEST(PropertyDescriptorCallback) {
}
}
+namespace {
int echo_indexed_call_count = 0;
-
+} // namespace
static void EchoIndexedProperty(
uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info) {
@@ -4560,7 +4578,7 @@ TEST(NamedAllCanReadInterceptor) {
ExpectInt32("checked.whatever", 17);
CHECK(!CompileRun("Object.getOwnPropertyDescriptor(checked, 'whatever')")
->IsUndefined());
- CHECK_EQ(6, access_check_data.count);
+ CHECK_EQ(5, access_check_data.count);
access_check_data.result = false;
ExpectInt32("checked.whatever", intercept_data_0.value);
@@ -4569,7 +4587,7 @@ TEST(NamedAllCanReadInterceptor) {
CompileRun("Object.getOwnPropertyDescriptor(checked, 'whatever')");
CHECK(try_catch.HasCaught());
}
- CHECK_EQ(9, access_check_data.count);
+ CHECK_EQ(7, access_check_data.count);
intercept_data_1.should_intercept = true;
ExpectInt32("checked.whatever", intercept_data_1.value);
@@ -4578,7 +4596,7 @@ TEST(NamedAllCanReadInterceptor) {
CompileRun("Object.getOwnPropertyDescriptor(checked, 'whatever')");
CHECK(try_catch.HasCaught());
}
- CHECK_EQ(12, access_check_data.count);
+ CHECK_EQ(9, access_check_data.count);
g_access_check_data = nullptr;
}
@@ -4647,7 +4665,7 @@ TEST(IndexedAllCanReadInterceptor) {
ExpectInt32("checked[15]", 17);
CHECK(!CompileRun("Object.getOwnPropertyDescriptor(checked, '15')")
->IsUndefined());
- CHECK_EQ(6, access_check_data.count);
+ CHECK_EQ(5, access_check_data.count);
access_check_data.result = false;
ExpectInt32("checked[15]", intercept_data_0.value);
@@ -4656,7 +4674,7 @@ TEST(IndexedAllCanReadInterceptor) {
CompileRun("Object.getOwnPropertyDescriptor(checked, '15')");
CHECK(try_catch.HasCaught());
}
- CHECK_EQ(9, access_check_data.count);
+ CHECK_EQ(7, access_check_data.count);
intercept_data_1.should_intercept = true;
ExpectInt32("checked[15]", intercept_data_1.value);
@@ -4665,7 +4683,7 @@ TEST(IndexedAllCanReadInterceptor) {
CompileRun("Object.getOwnPropertyDescriptor(checked, '15')");
CHECK(try_catch.HasCaught());
}
- CHECK_EQ(12, access_check_data.count);
+ CHECK_EQ(9, access_check_data.count);
g_access_check_data = nullptr;
}
diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc
index c578115888..24cbafbab1 100644
--- a/deps/v8/test/cctest/test-api.cc
+++ b/deps/v8/test/cctest/test-api.cc
@@ -1584,7 +1584,6 @@ THREADED_TEST(IsGeneratorFunctionOrObject) {
}
THREADED_TEST(IsAsyncFunction) {
- i::FLAG_harmony_async_await = true;
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope scope(isolate);
@@ -3325,6 +3324,20 @@ THREADED_TEST(GlobalSymbols) {
CHECK(!sym2->SameValue(glob_api));
}
+THREADED_TEST(GlobalSymbolsNoContext) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+
+ v8::Local<String> name = v8_str("my-symbol");
+ v8::Local<v8::Symbol> glob = v8::Symbol::For(isolate, name);
+ v8::Local<v8::Symbol> glob2 = v8::Symbol::For(isolate, name);
+ CHECK(glob2->SameValue(glob));
+
+ v8::Local<v8::Symbol> glob_api = v8::Symbol::ForApi(isolate, name);
+ v8::Local<v8::Symbol> glob_api2 = v8::Symbol::ForApi(isolate, name);
+ CHECK(glob_api2->SameValue(glob_api));
+ CHECK(!glob_api->SameValue(glob));
+}
static void CheckWellKnownSymbol(v8::Local<v8::Symbol>(*getter)(v8::Isolate*),
const char* name) {
@@ -4470,335 +4483,6 @@ static void WeakPointerCallback(
data.GetParameter()->handle.Reset();
}
-
-template <typename T>
-static UniqueId MakeUniqueId(const Persistent<T>& p) {
- return UniqueId(reinterpret_cast<uintptr_t>(*v8::Utils::OpenPersistent(p)));
-}
-
-
-THREADED_TEST(ApiObjectGroups) {
- LocalContext env;
- v8::Isolate* iso = env->GetIsolate();
- HandleScope scope(iso);
-
- WeakCallCounter counter(1234);
-
- WeakCallCounterAndPersistent<Value> g1s1(&counter);
- WeakCallCounterAndPersistent<Value> g1s2(&counter);
- WeakCallCounterAndPersistent<Value> g1c1(&counter);
- WeakCallCounterAndPersistent<Value> g2s1(&counter);
- WeakCallCounterAndPersistent<Value> g2s2(&counter);
- WeakCallCounterAndPersistent<Value> g2c1(&counter);
-
- {
- HandleScope scope(iso);
- g1s1.handle.Reset(iso, Object::New(iso));
- g1s2.handle.Reset(iso, Object::New(iso));
- g1c1.handle.Reset(iso, Object::New(iso));
- g1s1.handle.SetWeak(&g1s1, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
- g1s2.handle.SetWeak(&g1s2, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
- g1c1.handle.SetWeak(&g1c1, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
-
- g2s1.handle.Reset(iso, Object::New(iso));
- g2s2.handle.Reset(iso, Object::New(iso));
- g2c1.handle.Reset(iso, Object::New(iso));
- g2s1.handle.SetWeak(&g2s1, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
- g2s2.handle.SetWeak(&g2s2, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
- g2c1.handle.SetWeak(&g2c1, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
- }
-
- WeakCallCounterAndPersistent<Value> root(&counter);
- root.handle.Reset(iso, g1s1.handle); // make a root.
-
- // Connect group 1 and 2, make a cycle.
- {
- HandleScope scope(iso);
- CHECK(Local<Object>::New(iso, g1s2.handle.As<Object>())
- ->Set(env.local(), 0, Local<Value>::New(iso, g2s2.handle))
- .FromJust());
- CHECK(Local<Object>::New(iso, g2s1.handle.As<Object>())
- ->Set(env.local(), 0, Local<Value>::New(iso, g1s1.handle))
- .FromJust());
- }
-
- {
- UniqueId id1 = MakeUniqueId(g1s1.handle);
- UniqueId id2 = MakeUniqueId(g2s2.handle);
- iso->SetObjectGroupId(g1s1.handle, id1);
- iso->SetObjectGroupId(g1s2.handle, id1);
- iso->SetReferenceFromGroup(id1, g1c1.handle);
- iso->SetObjectGroupId(g2s1.handle, id2);
- iso->SetObjectGroupId(g2s2.handle, id2);
- iso->SetReferenceFromGroup(id2, g2c1.handle);
- }
- // Do a single full GC, ensure incremental marking is stopped.
- CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
-
- // All object should be alive.
- CHECK_EQ(0, counter.NumberOfWeakCalls());
-
- // Weaken the root.
- root.handle.SetWeak(&root, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
- // But make children strong roots---all the objects (except for children)
- // should be collectable now.
- g1c1.handle.ClearWeak();
- g2c1.handle.ClearWeak();
-
- // Groups are deleted, rebuild groups.
- {
- UniqueId id1 = MakeUniqueId(g1s1.handle);
- UniqueId id2 = MakeUniqueId(g2s2.handle);
- iso->SetObjectGroupId(g1s1.handle, id1);
- iso->SetObjectGroupId(g1s2.handle, id1);
- iso->SetReferenceFromGroup(id1, g1c1.handle);
- iso->SetObjectGroupId(g2s1.handle, id2);
- iso->SetObjectGroupId(g2s2.handle, id2);
- iso->SetReferenceFromGroup(id2, g2c1.handle);
- }
-
- CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
-
- // All objects should be gone. 5 global handles in total.
- CHECK_EQ(5, counter.NumberOfWeakCalls());
-
- // And now make children weak again and collect them.
- g1c1.handle.SetWeak(&g1c1, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
- g2c1.handle.SetWeak(&g2c1, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
-
- CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
- CHECK_EQ(7, counter.NumberOfWeakCalls());
-}
-
-
-THREADED_TEST(ApiObjectGroupsForSubtypes) {
- LocalContext env;
- v8::Isolate* iso = env->GetIsolate();
- HandleScope scope(iso);
-
- WeakCallCounter counter(1234);
-
- WeakCallCounterAndPersistent<Object> g1s1(&counter);
- WeakCallCounterAndPersistent<String> g1s2(&counter);
- WeakCallCounterAndPersistent<String> g1c1(&counter);
- WeakCallCounterAndPersistent<Object> g2s1(&counter);
- WeakCallCounterAndPersistent<String> g2s2(&counter);
- WeakCallCounterAndPersistent<String> g2c1(&counter);
-
- {
- HandleScope scope(iso);
- g1s1.handle.Reset(iso, Object::New(iso));
- g1s2.handle.Reset(iso, v8_str("foo1"));
- g1c1.handle.Reset(iso, v8_str("foo2"));
- g1s1.handle.SetWeak(&g1s1, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
- g1s2.handle.SetWeak(&g1s2, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
- g1c1.handle.SetWeak(&g1c1, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
-
- g2s1.handle.Reset(iso, Object::New(iso));
- g2s2.handle.Reset(iso, v8_str("foo3"));
- g2c1.handle.Reset(iso, v8_str("foo4"));
- g2s1.handle.SetWeak(&g2s1, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
- g2s2.handle.SetWeak(&g2s2, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
- g2c1.handle.SetWeak(&g2c1, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
- }
-
- WeakCallCounterAndPersistent<Value> root(&counter);
- root.handle.Reset(iso, g1s1.handle); // make a root.
-
- // Connect group 1 and 2, make a cycle.
- {
- HandleScope scope(iso);
- CHECK(Local<Object>::New(iso, g1s1.handle)
- ->Set(env.local(), 0, Local<Object>::New(iso, g2s1.handle))
- .FromJust());
- CHECK(Local<Object>::New(iso, g2s1.handle)
- ->Set(env.local(), 0, Local<Object>::New(iso, g1s1.handle))
- .FromJust());
- }
-
- {
- UniqueId id1 = MakeUniqueId(g1s1.handle);
- UniqueId id2 = MakeUniqueId(g2s2.handle);
- iso->SetObjectGroupId(g1s1.handle, id1);
- iso->SetObjectGroupId(g1s2.handle, id1);
- iso->SetReference(g1s1.handle, g1c1.handle);
- iso->SetObjectGroupId(g2s1.handle, id2);
- iso->SetObjectGroupId(g2s2.handle, id2);
- iso->SetReferenceFromGroup(id2, g2c1.handle);
- }
- // Do a single full GC, ensure incremental marking is stopped.
- CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
-
- // All object should be alive.
- CHECK_EQ(0, counter.NumberOfWeakCalls());
-
- // Weaken the root.
- root.handle.SetWeak(&root, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
- // But make children strong roots---all the objects (except for children)
- // should be collectable now.
- g1c1.handle.ClearWeak();
- g2c1.handle.ClearWeak();
-
- // Groups are deleted, rebuild groups.
- {
- UniqueId id1 = MakeUniqueId(g1s1.handle);
- UniqueId id2 = MakeUniqueId(g2s2.handle);
- iso->SetObjectGroupId(g1s1.handle, id1);
- iso->SetObjectGroupId(g1s2.handle, id1);
- iso->SetReference(g1s1.handle, g1c1.handle);
- iso->SetObjectGroupId(g2s1.handle, id2);
- iso->SetObjectGroupId(g2s2.handle, id2);
- iso->SetReferenceFromGroup(id2, g2c1.handle);
- }
-
- CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
-
- // All objects should be gone. 5 global handles in total.
- CHECK_EQ(5, counter.NumberOfWeakCalls());
-
- // And now make children weak again and collect them.
- g1c1.handle.SetWeak(&g1c1, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
- g2c1.handle.SetWeak(&g2c1, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
-
- CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
- CHECK_EQ(7, counter.NumberOfWeakCalls());
-}
-
-
-THREADED_TEST(ApiObjectGroupsCycle) {
- LocalContext env;
- v8::Isolate* iso = env->GetIsolate();
- HandleScope scope(iso);
-
- WeakCallCounter counter(1234);
-
- WeakCallCounterAndPersistent<Value> g1s1(&counter);
- WeakCallCounterAndPersistent<Value> g1s2(&counter);
- WeakCallCounterAndPersistent<Value> g2s1(&counter);
- WeakCallCounterAndPersistent<Value> g2s2(&counter);
- WeakCallCounterAndPersistent<Value> g3s1(&counter);
- WeakCallCounterAndPersistent<Value> g3s2(&counter);
- WeakCallCounterAndPersistent<Value> g4s1(&counter);
- WeakCallCounterAndPersistent<Value> g4s2(&counter);
-
- {
- HandleScope scope(iso);
- g1s1.handle.Reset(iso, Object::New(iso));
- g1s2.handle.Reset(iso, Object::New(iso));
- g1s1.handle.SetWeak(&g1s1, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
- g1s2.handle.SetWeak(&g1s2, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
- CHECK(g1s1.handle.IsWeak());
- CHECK(g1s2.handle.IsWeak());
-
- g2s1.handle.Reset(iso, Object::New(iso));
- g2s2.handle.Reset(iso, Object::New(iso));
- g2s1.handle.SetWeak(&g2s1, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
- g2s2.handle.SetWeak(&g2s2, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
- CHECK(g2s1.handle.IsWeak());
- CHECK(g2s2.handle.IsWeak());
-
- g3s1.handle.Reset(iso, Object::New(iso));
- g3s2.handle.Reset(iso, Object::New(iso));
- g3s1.handle.SetWeak(&g3s1, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
- g3s2.handle.SetWeak(&g3s2, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
- CHECK(g3s1.handle.IsWeak());
- CHECK(g3s2.handle.IsWeak());
-
- g4s1.handle.Reset(iso, Object::New(iso));
- g4s2.handle.Reset(iso, Object::New(iso));
- g4s1.handle.SetWeak(&g4s1, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
- g4s2.handle.SetWeak(&g4s2, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
- CHECK(g4s1.handle.IsWeak());
- CHECK(g4s2.handle.IsWeak());
- }
-
- WeakCallCounterAndPersistent<Value> root(&counter);
- root.handle.Reset(iso, g1s1.handle); // make a root.
-
- // Connect groups. We're building the following cycle:
- // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other
- // groups.
- {
- UniqueId id1 = MakeUniqueId(g1s1.handle);
- UniqueId id2 = MakeUniqueId(g2s1.handle);
- UniqueId id3 = MakeUniqueId(g3s1.handle);
- UniqueId id4 = MakeUniqueId(g4s1.handle);
- iso->SetObjectGroupId(g1s1.handle, id1);
- iso->SetObjectGroupId(g1s2.handle, id1);
- iso->SetReferenceFromGroup(id1, g2s1.handle);
- iso->SetObjectGroupId(g2s1.handle, id2);
- iso->SetObjectGroupId(g2s2.handle, id2);
- iso->SetReferenceFromGroup(id2, g3s1.handle);
- iso->SetObjectGroupId(g3s1.handle, id3);
- iso->SetObjectGroupId(g3s2.handle, id3);
- iso->SetReferenceFromGroup(id3, g4s1.handle);
- iso->SetObjectGroupId(g4s1.handle, id4);
- iso->SetObjectGroupId(g4s2.handle, id4);
- iso->SetReferenceFromGroup(id4, g1s1.handle);
- }
- // Do a single full GC
- CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
-
- // All object should be alive.
- CHECK_EQ(0, counter.NumberOfWeakCalls());
-
- // Weaken the root.
- root.handle.SetWeak(&root, &WeakPointerCallback,
- v8::WeakCallbackType::kParameter);
-
- // Groups are deleted, rebuild groups.
- {
- UniqueId id1 = MakeUniqueId(g1s1.handle);
- UniqueId id2 = MakeUniqueId(g2s1.handle);
- UniqueId id3 = MakeUniqueId(g3s1.handle);
- UniqueId id4 = MakeUniqueId(g4s1.handle);
- iso->SetObjectGroupId(g1s1.handle, id1);
- iso->SetObjectGroupId(g1s2.handle, id1);
- iso->SetReferenceFromGroup(id1, g2s1.handle);
- iso->SetObjectGroupId(g2s1.handle, id2);
- iso->SetObjectGroupId(g2s2.handle, id2);
- iso->SetReferenceFromGroup(id2, g3s1.handle);
- iso->SetObjectGroupId(g3s1.handle, id3);
- iso->SetObjectGroupId(g3s2.handle, id3);
- iso->SetReferenceFromGroup(id3, g4s1.handle);
- iso->SetObjectGroupId(g4s1.handle, id4);
- iso->SetObjectGroupId(g4s2.handle, id4);
- iso->SetReferenceFromGroup(id4, g1s1.handle);
- }
-
- CcTest::CollectAllGarbage(i::Heap::kFinalizeIncrementalMarkingMask);
-
- // All objects should be gone. 9 global handles in total.
- CHECK_EQ(9, counter.NumberOfWeakCalls());
-}
-
-
THREADED_TEST(ScriptException) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -4928,7 +4612,6 @@ static void check_message_3(v8::Local<v8::Message> message,
v8::Local<Value> data) {
CHECK(message->IsSharedCrossOrigin());
CHECK(message->GetScriptOrigin().Options().IsSharedCrossOrigin());
- CHECK(message->GetScriptOrigin().Options().IsEmbedderDebugScript());
CHECK(message->GetScriptOrigin().Options().IsOpaque());
CHECK_EQ(6.75, message->GetScriptOrigin()
.ResourceName()
@@ -4949,10 +4632,10 @@ TEST(MessageHandler3) {
CHECK(!message_received);
isolate->AddMessageListener(check_message_3);
LocalContext context;
- v8::ScriptOrigin origin = v8::ScriptOrigin(
- v8_str("6.75"), v8::Integer::New(isolate, 1),
- v8::Integer::New(isolate, 2), v8::True(isolate), Local<v8::Integer>(),
- v8::True(isolate), v8_str("7.40"), v8::True(isolate));
+ v8::ScriptOrigin origin =
+ v8::ScriptOrigin(v8_str("6.75"), v8::Integer::New(isolate, 1),
+ v8::Integer::New(isolate, 2), v8::True(isolate),
+ Local<v8::Integer>(), v8_str("7.40"), v8::True(isolate));
v8::Local<v8::Script> script =
Script::Compile(context.local(), v8_str("throw 'error'"), &origin)
.ToLocalChecked();
@@ -7086,6 +6769,9 @@ THREADED_TEST(Regress892105) {
.FromJust());
}
+static void ReturnThis(const v8::FunctionCallbackInfo<v8::Value>& args) {
+ args.GetReturnValue().Set(args.This());
+}
THREADED_TEST(UndetectableObject) {
LocalContext env;
@@ -7094,6 +6780,7 @@ THREADED_TEST(UndetectableObject) {
Local<v8::FunctionTemplate> desc =
v8::FunctionTemplate::New(env->GetIsolate());
desc->InstanceTemplate()->MarkAsUndetectable(); // undetectable
+ desc->InstanceTemplate()->SetCallAsFunctionHandler(ReturnThis); // callable
Local<v8::Object> obj = desc->GetFunction(env.local())
.ToLocalChecked()
@@ -7142,6 +6829,7 @@ THREADED_TEST(VoidLiteral) {
Local<v8::FunctionTemplate> desc = v8::FunctionTemplate::New(isolate);
desc->InstanceTemplate()->MarkAsUndetectable(); // undetectable
+ desc->InstanceTemplate()->SetCallAsFunctionHandler(ReturnThis); // callable
Local<v8::Object> obj = desc->GetFunction(env.local())
.ToLocalChecked()
@@ -7192,6 +6880,7 @@ THREADED_TEST(ExtensibleOnUndetectable) {
Local<v8::FunctionTemplate> desc = v8::FunctionTemplate::New(isolate);
desc->InstanceTemplate()->MarkAsUndetectable(); // undetectable
+ desc->InstanceTemplate()->SetCallAsFunctionHandler(ReturnThis); // callable
Local<v8::Object> obj = desc->GetFunction(env.local())
.ToLocalChecked()
@@ -7811,7 +7500,8 @@ static void IndependentWeakHandle(bool global_gc, bool interlinked) {
}
// A single GC should be enough to reclaim the memory, since we are using
// phantom handles.
- CHECK_LT(CcTest::heap()->SizeOfObjects(), big_heap_size - 20000);
+ // BUG(5865): --expose-wasm with no snapshot builds requires a limit change.
+ CHECK_LT(CcTest::heap()->SizeOfObjects(), big_heap_size - 19000);
CHECK(object_a.flag);
CHECK(object_b.flag);
}
@@ -11776,11 +11466,6 @@ static void call_as_function(const v8::FunctionCallbackInfo<v8::Value>& args) {
}
-static void ReturnThis(const v8::FunctionCallbackInfo<v8::Value>& args) {
- args.GetReturnValue().Set(args.This());
-}
-
-
// Test that a call handler can be set for objects which will allow
// non-function objects created through the API to be called as
// functions.
@@ -14561,17 +14246,22 @@ void SetFunctionEntryHookTest::RunTest() {
RunLoopInNewEnv(isolate);
// Check the expected invocation counts.
- if (!i::FLAG_ignition && !i::FLAG_turbo) {
+ if (i::FLAG_always_opt || (!i::FLAG_ignition && !i::FLAG_turbo)) {
CHECK_EQ(2, CountInvocations(NULL, "bar"));
CHECK_EQ(200, CountInvocations("bar", "foo"));
CHECK_EQ(200, CountInvocations(NULL, "foo"));
- } else {
+ } else if (i::FLAG_crankshaft || i::FLAG_turbo) {
// For ignition we don't see the actual functions being called, instead
- // we see the IterpreterEntryTrampoline at least 102 times
+ // we see the InterpreterEntryTrampoline at least 102 times
// (100 unoptimized calls to foo, and 2 calls to bar).
CHECK_LE(102, CountInvocations(NULL, "InterpreterEntryTrampoline"));
// We should also see the calls to the optimized function foo.
CHECK_EQ(100, CountInvocations(NULL, "foo"));
+ } else {
+ // For ignition without an optimizing compiler, we should only see the
+ // InterpreterEntryTrampoline.
+ // (200 unoptimized calls to foo, and 2 calls to bar).
+ CHECK_LE(202, CountInvocations(NULL, "InterpreterEntryTrampoline"));
}
// Verify that we have an entry hook on some specific stubs.
@@ -15364,7 +15054,6 @@ TEST(PreCompileSerialization) {
v8::Isolate* isolate = env->GetIsolate();
HandleScope handle_scope(isolate);
- i::FLAG_min_preparse_length = 0;
const char* script = "function foo(a) { return a+1; }";
v8::ScriptCompiler::Source source(v8_str(script));
v8::ScriptCompiler::Compile(env.local(), &source,
@@ -17336,6 +17025,79 @@ TEST(CaptureStackTraceForUncaughtExceptionAndSetters) {
isolate->SetCaptureStackTraceForUncaughtExceptions(false);
}
+static int asm_warning_triggered = 0;
+
+static void AsmJsWarningListener(v8::Local<v8::Message> message,
+ v8::Local<Value>) {
+ DCHECK_EQ(v8::Isolate::kMessageWarning, message->ErrorLevel());
+ asm_warning_triggered = 1;
+}
+
+TEST(AsmJsWarning) {
+ i::FLAG_validate_asm = true;
+
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+
+ asm_warning_triggered = 0;
+ isolate->AddMessageListenerWithErrorLevel(AsmJsWarningListener,
+ v8::Isolate::kMessageAll);
+ CompileRun(
+ "function module() {\n"
+ " 'use asm';\n"
+ " var x = 'hi';\n"
+ " return {};\n"
+ "}\n"
+ "module();");
+ DCHECK_EQ(1, asm_warning_triggered);
+ isolate->RemoveMessageListeners(AsmJsWarningListener);
+}
+
+static int error_level_message_count = 0;
+static int expected_error_level = 0;
+
+static void ErrorLevelListener(v8::Local<v8::Message> message,
+ v8::Local<Value>) {
+ DCHECK_EQ(expected_error_level, message->ErrorLevel());
+ ++error_level_message_count;
+}
+
+TEST(ErrorLevelWarning) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ v8::HandleScope scope(isolate);
+
+ const char* source = "fake = 1;";
+ v8::Local<v8::Script> lscript = CompileWithOrigin(source, "test");
+ i::Handle<i::SharedFunctionInfo> obj = i::Handle<i::SharedFunctionInfo>::cast(
+ v8::Utils::OpenHandle(*lscript->GetUnboundScript()));
+ CHECK(obj->script()->IsScript());
+ i::Handle<i::Script> script(i::Script::cast(obj->script()));
+
+ int levels[] = {
+ v8::Isolate::kMessageLog, v8::Isolate::kMessageInfo,
+ v8::Isolate::kMessageDebug, v8::Isolate::kMessageWarning,
+ };
+ error_level_message_count = 0;
+ isolate->AddMessageListenerWithErrorLevel(ErrorLevelListener,
+ v8::Isolate::kMessageAll);
+ for (size_t i = 0; i < arraysize(levels); i++) {
+ i::MessageLocation location(script, 0, 0);
+ i::Handle<i::String> msg(i_isolate->factory()->InternalizeOneByteString(
+ STATIC_CHAR_VECTOR("test")));
+ i::Handle<i::JSMessageObject> message =
+ i::MessageHandler::MakeMessageObject(
+ i_isolate, i::MessageTemplate::kAsmJsInvalid, &location, msg,
+ i::Handle<i::JSArray>::null());
+ message->set_error_level(levels[i]);
+ expected_error_level = levels[i];
+ i::MessageHandler::ReportMessage(i_isolate, &location, message);
+ }
+ isolate->RemoveMessageListeners(ErrorLevelListener);
+ DCHECK_EQ(arraysize(levels), error_level_message_count);
+}
static void StackTraceFunctionNameListener(v8::Local<v8::Message> message,
v8::Local<Value>) {
@@ -18053,6 +17815,348 @@ TEST(InlineScriptWithSourceURLInStackTrace) {
CHECK(CompileRunWithOrigin(code.start(), "url", 0, 1)->IsUndefined());
}
+void SetPromise(const char* name, v8::Local<v8::Promise> promise) {
+ CcTest::global()
+ ->Set(CcTest::isolate()->GetCurrentContext(), v8_str(name), promise)
+ .FromJust();
+}
+
+class PromiseHookData {
+ public:
+ int before_hook_count = 0;
+ int after_hook_count = 0;
+ int promise_hook_count = 0;
+ int parent_promise_count = 0;
+ bool check_value = true;
+ std::string promise_hook_value;
+
+ void Reset() {
+ before_hook_count = 0;
+ after_hook_count = 0;
+ promise_hook_count = 0;
+ parent_promise_count = 0;
+ check_value = true;
+ promise_hook_value = "";
+ }
+};
+
+PromiseHookData* promise_hook_data;
+
+void CustomPromiseHook(v8::PromiseHookType type, v8::Local<v8::Promise> promise,
+ v8::Local<v8::Value> parentPromise) {
+ promise_hook_data->promise_hook_count++;
+ switch (type) {
+ case v8::PromiseHookType::kInit:
+ SetPromise("init", promise);
+
+ if (!parentPromise->IsUndefined()) {
+ promise_hook_data->parent_promise_count++;
+ SetPromise("parent", v8::Local<v8::Promise>::Cast(parentPromise));
+ }
+
+ break;
+ case v8::PromiseHookType::kResolve:
+ SetPromise("resolve", promise);
+ break;
+ case v8::PromiseHookType::kBefore:
+ promise_hook_data->before_hook_count++;
+ CHECK(promise_hook_data->before_hook_count >
+ promise_hook_data->after_hook_count);
+ CHECK(CcTest::global()
+ ->Get(CcTest::isolate()->GetCurrentContext(), v8_str("value"))
+ .ToLocalChecked()
+ ->Equals(CcTest::isolate()->GetCurrentContext(), v8_str(""))
+ .FromJust());
+ SetPromise("before", promise);
+ break;
+ case v8::PromiseHookType::kAfter:
+ promise_hook_data->after_hook_count++;
+ CHECK(promise_hook_data->after_hook_count <=
+ promise_hook_data->before_hook_count);
+ if (promise_hook_data->check_value) {
+ CHECK(
+ CcTest::global()
+ ->Get(CcTest::isolate()->GetCurrentContext(), v8_str("value"))
+ .ToLocalChecked()
+ ->Equals(CcTest::isolate()->GetCurrentContext(),
+ v8_str(promise_hook_data->promise_hook_value.c_str()))
+ .FromJust());
+ }
+ SetPromise("after", promise);
+ break;
+ }
+}
+
+TEST(PromiseHook) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+
+ v8::Local<v8::Object> global = CcTest::global();
+ v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext();
+
+ promise_hook_data = new PromiseHookData();
+ isolate->SetPromiseHook(CustomPromiseHook);
+
+ // Test that an initialized promise is passed to init. Other hooks
+ // can not have un initialized promise.
+ promise_hook_data->check_value = false;
+ CompileRun("var p = new Promise(() => {});");
+
+ auto init_promise = global->Get(context, v8_str("init")).ToLocalChecked();
+ CHECK(GetPromise("p")->Equals(env.local(), init_promise).FromJust());
+ auto init_promise_obj = v8::Local<v8::Promise>::Cast(init_promise);
+ CHECK(init_promise_obj->State() == v8::Promise::PromiseState::kPending);
+ CHECK_EQ(false, init_promise_obj->HasHandler());
+
+ promise_hook_data->Reset();
+ promise_hook_data->promise_hook_value = "fulfilled";
+ const char* source =
+ "var resolve, value = ''; \n"
+ "var p = new Promise(r => resolve = r); \n";
+
+ CompileRun(source);
+ init_promise = global->Get(context, v8_str("init")).ToLocalChecked();
+ CHECK(GetPromise("p")->Equals(env.local(), init_promise).FromJust());
+ CHECK_EQ(1, promise_hook_data->promise_hook_count);
+ CHECK_EQ(0, promise_hook_data->parent_promise_count);
+
+ CompileRun("var p1 = p.then(() => { value = 'fulfilled'; }); \n");
+ init_promise = global->Get(context, v8_str("init")).ToLocalChecked();
+ auto parent_promise = global->Get(context, v8_str("parent")).ToLocalChecked();
+ CHECK(GetPromise("p1")->Equals(env.local(), init_promise).FromJust());
+ CHECK(GetPromise("p")->Equals(env.local(), parent_promise).FromJust());
+ CHECK_EQ(2, promise_hook_data->promise_hook_count);
+ CHECK_EQ(1, promise_hook_data->parent_promise_count);
+
+ CompileRun("resolve(); \n");
+ auto resolve_promise =
+ global->Get(context, v8_str("resolve")).ToLocalChecked();
+ auto before_promise = global->Get(context, v8_str("before")).ToLocalChecked();
+ auto after_promise = global->Get(context, v8_str("after")).ToLocalChecked();
+ CHECK(GetPromise("p1")->Equals(env.local(), before_promise).FromJust());
+ CHECK(GetPromise("p1")->Equals(env.local(), after_promise).FromJust());
+ CHECK(GetPromise("p1")->Equals(env.local(), resolve_promise).FromJust());
+ CHECK_EQ(6, promise_hook_data->promise_hook_count);
+
+ CompileRun("value = ''; var p2 = p1.then(() => { value = 'fulfilled' }); \n");
+ init_promise = global->Get(context, v8_str("init")).ToLocalChecked();
+ parent_promise = global->Get(context, v8_str("parent")).ToLocalChecked();
+ resolve_promise = global->Get(context, v8_str("resolve")).ToLocalChecked();
+ before_promise = global->Get(context, v8_str("before")).ToLocalChecked();
+ after_promise = global->Get(context, v8_str("after")).ToLocalChecked();
+ CHECK(GetPromise("p2")->Equals(env.local(), init_promise).FromJust());
+ CHECK(GetPromise("p1")->Equals(env.local(), parent_promise).FromJust());
+ CHECK(GetPromise("p2")->Equals(env.local(), before_promise).FromJust());
+ CHECK(GetPromise("p2")->Equals(env.local(), after_promise).FromJust());
+ CHECK(GetPromise("p2")->Equals(env.local(), resolve_promise).FromJust());
+ CHECK_EQ(10, promise_hook_data->promise_hook_count);
+
+ promise_hook_data->Reset();
+ promise_hook_data->promise_hook_value = "rejected";
+ source =
+ "var reject, value = ''; \n"
+ "var p = new Promise((_, r) => reject = r); \n";
+
+ CompileRun(source);
+ init_promise = global->Get(context, v8_str("init")).ToLocalChecked();
+ CHECK(GetPromise("p")->Equals(env.local(), init_promise).FromJust());
+ CHECK_EQ(1, promise_hook_data->promise_hook_count);
+ CHECK_EQ(0, promise_hook_data->parent_promise_count);
+
+ CompileRun("var p1 = p.catch(() => { value = 'rejected'; }); \n");
+ init_promise = global->Get(context, v8_str("init")).ToLocalChecked();
+ parent_promise = global->Get(context, v8_str("parent")).ToLocalChecked();
+ CHECK(GetPromise("p1")->Equals(env.local(), init_promise).FromJust());
+ CHECK(GetPromise("p")->Equals(env.local(), parent_promise).FromJust());
+ CHECK_EQ(2, promise_hook_data->promise_hook_count);
+ CHECK_EQ(1, promise_hook_data->parent_promise_count);
+
+ CompileRun("reject(); \n");
+ resolve_promise = global->Get(context, v8_str("resolve")).ToLocalChecked();
+ before_promise = global->Get(context, v8_str("before")).ToLocalChecked();
+ after_promise = global->Get(context, v8_str("after")).ToLocalChecked();
+ CHECK(GetPromise("p1")->Equals(env.local(), before_promise).FromJust());
+ CHECK(GetPromise("p1")->Equals(env.local(), after_promise).FromJust());
+ CHECK(GetPromise("p1")->Equals(env.local(), resolve_promise).FromJust());
+ CHECK_EQ(6, promise_hook_data->promise_hook_count);
+
+ promise_hook_data->Reset();
+ promise_hook_data->promise_hook_value = "Promise.resolve";
+ source =
+ "var value = ''; \n"
+ "var p = Promise.resolve('Promise.resolve'); \n";
+
+ CompileRun(source);
+ init_promise = global->Get(context, v8_str("init")).ToLocalChecked();
+ CHECK(GetPromise("p")->Equals(env.local(), init_promise).FromJust());
+ // init hook and resolve hook
+ CHECK_EQ(2, promise_hook_data->promise_hook_count);
+ CHECK_EQ(0, promise_hook_data->parent_promise_count);
+ resolve_promise = global->Get(context, v8_str("resolve")).ToLocalChecked();
+ CHECK(GetPromise("p")->Equals(env.local(), resolve_promise).FromJust());
+
+ CompileRun("var p1 = p.then((v) => { value = v; }); \n");
+ init_promise = global->Get(context, v8_str("init")).ToLocalChecked();
+ resolve_promise = global->Get(context, v8_str("resolve")).ToLocalChecked();
+ parent_promise = global->Get(context, v8_str("parent")).ToLocalChecked();
+ before_promise = global->Get(context, v8_str("before")).ToLocalChecked();
+ after_promise = global->Get(context, v8_str("after")).ToLocalChecked();
+ CHECK(GetPromise("p1")->Equals(env.local(), init_promise).FromJust());
+ CHECK(GetPromise("p1")->Equals(env.local(), resolve_promise).FromJust());
+ CHECK(GetPromise("p")->Equals(env.local(), parent_promise).FromJust());
+ CHECK(GetPromise("p1")->Equals(env.local(), before_promise).FromJust());
+ CHECK(GetPromise("p1")->Equals(env.local(), after_promise).FromJust());
+ CHECK_EQ(6, promise_hook_data->promise_hook_count);
+ CHECK_EQ(1, promise_hook_data->parent_promise_count);
+
+ promise_hook_data->Reset();
+ source =
+ "var resolve, value = ''; \n"
+ "var p = new Promise((_, r) => resolve = r); \n";
+
+ CompileRun(source);
+ init_promise = global->Get(context, v8_str("init")).ToLocalChecked();
+ CHECK(GetPromise("p")->Equals(env.local(), init_promise).FromJust());
+ CHECK_EQ(1, promise_hook_data->promise_hook_count);
+ CHECK_EQ(0, promise_hook_data->parent_promise_count);
+
+ CompileRun("resolve(); \n");
+ resolve_promise = global->Get(context, v8_str("resolve")).ToLocalChecked();
+ CHECK(GetPromise("p")->Equals(env.local(), resolve_promise).FromJust());
+ CHECK_EQ(2, promise_hook_data->promise_hook_count);
+
+ promise_hook_data->Reset();
+ source =
+ "var reject, value = ''; \n"
+ "var p = new Promise((_, r) => reject = r); \n";
+
+ CompileRun(source);
+ init_promise = global->Get(context, v8_str("init")).ToLocalChecked();
+ CHECK(GetPromise("p")->Equals(env.local(), init_promise).FromJust());
+ CHECK_EQ(1, promise_hook_data->promise_hook_count);
+ CHECK_EQ(0, promise_hook_data->parent_promise_count);
+
+ CompileRun("reject(); \n");
+ resolve_promise = global->Get(context, v8_str("resolve")).ToLocalChecked();
+ CHECK(GetPromise("p")->Equals(env.local(), resolve_promise).FromJust());
+ CHECK_EQ(2, promise_hook_data->promise_hook_count);
+
+ promise_hook_data->Reset();
+ // This test triggers after callbacks right after each other, so
+ // lets just check the value at the end.
+ promise_hook_data->check_value = false;
+ promise_hook_data->promise_hook_value = "Promise.all";
+ source =
+ "var resolve, value = ''; \n"
+ "var tempPromise = new Promise(r => resolve = r); \n"
+ "var p = Promise.all([tempPromise]);\n "
+ "var p1 = p.then(v => value = v[0]); \n";
+
+ CompileRun(source);
+ // 1) init hook (tempPromise)
+ // 2) init hook (p)
+ // 3) init hook (throwaway Promise in Promise.all, p)
+ // 4) init hook (p1, p)
+ CHECK_EQ(4, promise_hook_data->promise_hook_count);
+ CHECK_EQ(2, promise_hook_data->parent_promise_count);
+
+ promise_hook_data->promise_hook_value = "Promise.all";
+ CompileRun("resolve('Promise.all'); \n");
+ resolve_promise = global->Get(context, v8_str("resolve")).ToLocalChecked();
+ CHECK(GetPromise("p1")->Equals(env.local(), resolve_promise).FromJust());
+ // 5) resolve hook (tempPromise)
+ // 6) resolve hook (throwaway Promise in Promise.all)
+ // 6) before hook (throwaway Promise in Promise.all)
+ // 7) after hook (throwaway Promise in Promise.all)
+ // 8) before hook (p)
+ // 9) after hook (p)
+ // 10) resolve hook (p1)
+ // 11) before hook (p1)
+ // 12) after hook (p1)
+ CHECK_EQ(12, promise_hook_data->promise_hook_count);
+ CHECK(CcTest::global()
+ ->Get(CcTest::isolate()->GetCurrentContext(), v8_str("value"))
+ .ToLocalChecked()
+ ->Equals(CcTest::isolate()->GetCurrentContext(),
+ v8_str(promise_hook_data->promise_hook_value.c_str()))
+ .FromJust());
+
+ promise_hook_data->Reset();
+ // This test triggers after callbacks right after each other, so
+ // lets just check the value at the end.
+ promise_hook_data->check_value = false;
+ promise_hook_data->promise_hook_value = "Promise.race";
+ source =
+ "var resolve, value = ''; \n"
+ "var tempPromise = new Promise(r => resolve = r); \n"
+ "var p = Promise.race([tempPromise]);\n "
+ "var p1 = p.then(v => value = v); \n";
+
+ CompileRun(source);
+ // 1) init hook (tempPromise)
+ // 2) init hook (p)
+ // 3) init hook (throwaway Promise in Promise.race, p)
+ // 4) init hook (p1, p)
+ CHECK_EQ(4, promise_hook_data->promise_hook_count);
+ CHECK_EQ(2, promise_hook_data->parent_promise_count);
+
+ promise_hook_data->promise_hook_value = "Promise.race";
+ CompileRun("resolve('Promise.race'); \n");
+ resolve_promise = global->Get(context, v8_str("resolve")).ToLocalChecked();
+ CHECK(GetPromise("p1")->Equals(env.local(), resolve_promise).FromJust());
+ // 5) resolve hook (tempPromise)
+ // 6) resolve hook (throwaway Promise in Promise.race)
+ // 6) before hook (throwaway Promise in Promise.race)
+ // 7) after hook (throwaway Promise in Promise.race)
+ // 8) before hook (p)
+ // 9) after hook (p)
+ // 10) resolve hook (p1)
+ // 11) before hook (p1)
+ // 12) after hook (p1)
+ CHECK_EQ(12, promise_hook_data->promise_hook_count);
+ CHECK(CcTest::global()
+ ->Get(CcTest::isolate()->GetCurrentContext(), v8_str("value"))
+ .ToLocalChecked()
+ ->Equals(CcTest::isolate()->GetCurrentContext(),
+ v8_str(promise_hook_data->promise_hook_value.c_str()))
+ .FromJust());
+
+ promise_hook_data->Reset();
+ promise_hook_data->promise_hook_value = "subclass";
+ source =
+ "var resolve, value = '';\n"
+ "class MyPromise extends Promise { \n"
+ " then(onFulfilled, onRejected) { \n"
+ " return super.then(onFulfilled, onRejected); \n"
+ " };\n"
+ "};\n"
+ "var p = new MyPromise(r => resolve = r);\n";
+
+ CompileRun(source);
+ // 1) init hook (p)
+ CHECK_EQ(1, promise_hook_data->promise_hook_count);
+
+ CompileRun("var p1 = p.then(() => value = 'subclass');\n");
+ // 2) init hook (p1)
+ CHECK_EQ(2, promise_hook_data->promise_hook_count);
+
+ CompileRun("resolve();\n");
+ resolve_promise = global->Get(context, v8_str("resolve")).ToLocalChecked();
+ before_promise = global->Get(context, v8_str("before")).ToLocalChecked();
+ after_promise = global->Get(context, v8_str("after")).ToLocalChecked();
+ CHECK(GetPromise("p1")->Equals(env.local(), before_promise).FromJust());
+ CHECK(GetPromise("p1")->Equals(env.local(), after_promise).FromJust());
+ CHECK(GetPromise("p1")->Equals(env.local(), resolve_promise).FromJust());
+ // 3) resolve hook (p)
+ // 4) before hook (p)
+ // 5) after hook (p)
+ // 6) resolve hook (p1)
+ CHECK_EQ(6, promise_hook_data->promise_hook_count);
+
+ delete promise_hook_data;
+ isolate->SetPromiseHook(nullptr);
+}
void AnalyzeStackOfDynamicScriptWithSourceURL(
const v8::FunctionCallbackInfo<v8::Value>& args) {
@@ -18773,8 +18877,8 @@ THREADED_TEST(ScriptOrigin) {
v8::ScriptOrigin origin = v8::ScriptOrigin(
v8_str("test"), v8::Integer::New(env->GetIsolate(), 1),
v8::Integer::New(env->GetIsolate(), 1), v8::True(env->GetIsolate()),
- v8::Local<v8::Integer>(), v8::True(env->GetIsolate()),
- v8_str("http://sourceMapUrl"), v8::True(env->GetIsolate()));
+ v8::Local<v8::Integer>(), v8_str("http://sourceMapUrl"),
+ v8::True(env->GetIsolate()));
v8::Local<v8::String> script = v8_str("function f() {}\n\nfunction g() {}");
v8::Script::Compile(env.local(), script, &origin)
.ToLocalChecked()
@@ -18792,7 +18896,6 @@ THREADED_TEST(ScriptOrigin) {
1,
script_origin_f.ResourceLineOffset()->Int32Value(env.local()).FromJust());
CHECK(script_origin_f.Options().IsSharedCrossOrigin());
- CHECK(script_origin_f.Options().IsEmbedderDebugScript());
CHECK(script_origin_f.Options().IsOpaque());
printf("is name = %d\n", script_origin_f.SourceMapUrl()->IsUndefined());
@@ -18806,7 +18909,6 @@ THREADED_TEST(ScriptOrigin) {
1,
script_origin_g.ResourceLineOffset()->Int32Value(env.local()).FromJust());
CHECK(script_origin_g.Options().IsSharedCrossOrigin());
- CHECK(script_origin_g.Options().IsEmbedderDebugScript());
CHECK(script_origin_g.Options().IsOpaque());
CHECK_EQ(0, strcmp("http://sourceMapUrl",
*v8::String::Utf8Value(script_origin_g.SourceMapUrl())));
@@ -19018,24 +19120,6 @@ THREADED_TEST(ScriptColumnNumber) {
}
-THREADED_TEST(FunctionIsBuiltin) {
- LocalContext env;
- v8::Isolate* isolate = env->GetIsolate();
- v8::HandleScope scope(isolate);
- v8::Local<v8::Function> f;
- f = v8::Local<v8::Function>::Cast(CompileRun("Math.floor"));
- CHECK(f->IsBuiltin());
- f = v8::Local<v8::Function>::Cast(CompileRun("Object"));
- CHECK(f->IsBuiltin());
- f = v8::Local<v8::Function>::Cast(CompileRun("Object.__defineSetter__"));
- CHECK(f->IsBuiltin());
- f = v8::Local<v8::Function>::Cast(CompileRun("Array.prototype.toString"));
- CHECK(f->IsBuiltin());
- f = v8::Local<v8::Function>::Cast(CompileRun("function a() {}; a;"));
- CHECK(!f->IsBuiltin());
-}
-
-
THREADED_TEST(FunctionGetScriptId) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
@@ -21753,6 +21837,19 @@ int* LookupCounter(const char* name) {
return NULL;
}
+template <typename Stub, typename... Args>
+void Recompile(Args... args) {
+ Stub stub(args...);
+ stub.DeleteStubFromCacheForTesting();
+ stub.GetCode();
+}
+
+void RecompileICStubs(i::Isolate* isolate) {
+ // BUG(5784): We had a list of IC stubs here to recompile. These are now
+ // builtins and we can't compile them again (easily). Bug 5784 tracks
+ // our progress in finding another way to do this.
+}
+
} // namespace
#ifdef ENABLE_DISASSEMBLER
@@ -21786,46 +21883,35 @@ const char* kMegamorphicTestProgram =
"}\n";
void TestStubCache(bool primary) {
+ using namespace i;
+
// The test does not work with interpreter because bytecode handlers taken
// from the snapshot already refer to ICs with disabled counters and there
// is no way to trigger bytecode handlers recompilation.
- if (i::FLAG_ignition || i::FLAG_turbo) return;
+ if (FLAG_ignition || FLAG_turbo) return;
- i::FLAG_native_code_counters = true;
+ FLAG_native_code_counters = true;
if (primary) {
- i::FLAG_test_primary_stub_cache = true;
+ FLAG_test_primary_stub_cache = true;
} else {
- i::FLAG_test_secondary_stub_cache = true;
+ FLAG_test_secondary_stub_cache = true;
}
- i::FLAG_crankshaft = false;
- i::FLAG_turbo = false;
+ FLAG_crankshaft = false;
+
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
create_params.counter_lookup_callback = LookupCounter;
v8::Isolate* isolate = v8::Isolate::New(create_params);
+ Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate);
{
v8::Isolate::Scope isolate_scope(isolate);
LocalContext env(isolate);
v8::HandleScope scope(isolate);
- {
- // Enforce recompilation of IC stubs that access megamorphic stub cache
- // to respect enabled native code counters and stub cache test flags.
- i::CodeStub::Major code_stub_keys[] = {
- i::CodeStub::LoadIC, i::CodeStub::LoadICTrampoline,
- i::CodeStub::KeyedLoadICTF, i::CodeStub::KeyedLoadICTrampolineTF,
- i::CodeStub::StoreIC, i::CodeStub::StoreICTrampoline,
- i::CodeStub::KeyedStoreIC, i::CodeStub::KeyedStoreICTrampoline,
- };
- i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- i::Heap* heap = i_isolate->heap();
- i::Handle<i::UnseededNumberDictionary> dict(heap->code_stubs());
- for (size_t i = 0; i < arraysize(code_stub_keys); i++) {
- dict = i::UnseededNumberDictionary::DeleteKey(dict, code_stub_keys[i]);
- }
- heap->SetRootCodeStubs(*dict);
- }
+ // Enforce recompilation of IC stubs that access megamorphic stub cache
+ // to respect enabled native code counters and stub cache test flags.
+ RecompileICStubs(i_isolate);
int initial_probes = probes_counter;
int initial_misses = misses_counter;
@@ -22718,41 +22804,30 @@ TEST(AccessCheckThrows) {
}
TEST(AccessCheckInIC) {
+ using namespace i;
+
// The test does not work with interpreter because bytecode handlers taken
// from the snapshot already refer to ICs with disabled counters and there
// is no way to trigger bytecode handlers recompilation.
- if (i::FLAG_ignition || i::FLAG_turbo) return;
+ if (FLAG_ignition || FLAG_turbo) return;
+
+ FLAG_native_code_counters = true;
+ FLAG_crankshaft = false;
- i::FLAG_native_code_counters = true;
- i::FLAG_crankshaft = false;
- i::FLAG_turbo = false;
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
create_params.counter_lookup_callback = LookupCounter;
v8::Isolate* isolate = v8::Isolate::New(create_params);
+ Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate);
{
v8::Isolate::Scope isolate_scope(isolate);
LocalContext env(isolate);
v8::HandleScope scope(isolate);
- {
- // Enforce recompilation of IC stubs that access megamorphic stub cache
- // to respect enabled native code counters and stub cache test flags.
- i::CodeStub::Major code_stub_keys[] = {
- i::CodeStub::LoadIC, i::CodeStub::LoadICTrampoline,
- i::CodeStub::KeyedLoadICTF, i::CodeStub::KeyedLoadICTrampolineTF,
- i::CodeStub::StoreIC, i::CodeStub::StoreICTrampoline,
- i::CodeStub::KeyedStoreIC, i::CodeStub::KeyedStoreICTrampoline,
- };
- i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- i::Heap* heap = i_isolate->heap();
- i::Handle<i::UnseededNumberDictionary> dict(heap->code_stubs());
- for (size_t i = 0; i < arraysize(code_stub_keys); i++) {
- dict = i::UnseededNumberDictionary::DeleteKey(dict, code_stub_keys[i]);
- }
- heap->SetRootCodeStubs(*dict);
- }
+ // Enforce recompilation of IC stubs that access megamorphic stub cache
+ // to respect enabled native code counters and stub cache test flags.
+ RecompileICStubs(i_isolate);
// Create an ObjectTemplate for global objects and install access
// check callbacks that will block access.
@@ -23228,20 +23303,15 @@ THREADED_TEST(FunctionNew) {
CHECK(env->Global()->Set(env.local(), v8_str("func"), func).FromJust());
Local<Value> result = CompileRun("func();");
CHECK(v8::Integer::New(isolate, 17)->Equals(env.local(), result).FromJust());
- i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- // Verify function not cached
- auto serial_number = handle(
+ // Serial number should be invalid => should not be cached.
+ auto serial_number =
i::Smi::cast(i::Handle<i::JSFunction>::cast(v8::Utils::OpenHandle(*func))
->shared()
->get_api_func_data()
- ->serial_number()),
- i_isolate);
- auto slow_cache = i_isolate->slow_template_instantiations_cache();
- CHECK(slow_cache->FindEntry(static_cast<uint32_t>(serial_number->value())) ==
- i::UnseededNumberDictionary::kNotFound);
- auto fast_cache = i_isolate->fast_template_instantiations_cache();
- CHECK(fast_cache->get(static_cast<uint32_t>(serial_number->value()))
- ->IsUndefined(i_isolate));
+ ->serial_number())
+ ->value();
+ CHECK_EQ(i::FunctionTemplateInfo::kInvalidSerialNumber, serial_number);
+
// Verify that each Function::New creates a new function instance
Local<Object> data2 = v8::Object::New(isolate);
function_new_expected_env = data2;
@@ -23986,6 +24056,25 @@ TEST(PromiseThen) {
.FromJust());
}
+TEST(PromiseStateAndValue) {
+ LocalContext context;
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+ v8::Local<v8::Value> result = CompileRun(
+ "var resolver;"
+ "new Promise((res, rej) => { resolver = res; })");
+ v8::Local<v8::Promise> promise = v8::Local<v8::Promise>::Cast(result);
+ CHECK(promise->State() == v8::Promise::PromiseState::kPending);
+
+ CompileRun("resolver('fulfilled')");
+ CHECK(promise->State() == v8::Promise::PromiseState::kFulfilled);
+ CHECK(v8_str("fulfilled")->SameValue(promise->Result()));
+
+ result = CompileRun("Promise.reject('rejected')");
+ promise = v8::Local<v8::Promise>::Cast(result);
+ CHECK(promise->State() == v8::Promise::PromiseState::kRejected);
+ CHECK(v8_str("rejected")->SameValue(promise->Result()));
+}
TEST(DisallowJavascriptExecutionScope) {
LocalContext context;
@@ -24691,7 +24780,6 @@ TEST(StreamingUtf8ScriptWithSplitCharactersInvalidEdgeCases) {
TEST(StreamingProducesParserCache) {
- i::FLAG_min_preparse_length = 0;
const char* chunks[] = {"function foo() { ret", "urn 13; } f", "oo(); ",
NULL};
@@ -24724,7 +24812,6 @@ TEST(StreamingWithDebuggingEnabledLate) {
// fully parsed. However, we may compile inner functions eagerly when
// debugging. Make sure that we can deal with this when turning on debugging
// after streaming parser has already finished parsing.
- i::FLAG_min_preparse_length = 0;
const char* chunks[] = {"with({x:1}) {",
" var foo = function foo(y) {",
" return x + y;",
@@ -24971,7 +25058,6 @@ TEST(ParserCacheRejectedGracefully) {
// Producing cached parser data while parsing eagerly is not supported.
if (!i::FLAG_lazy) return;
- i::FLAG_min_preparse_length = 0;
v8::V8::Initialize();
v8::HandleScope scope(CcTest::isolate());
LocalContext context;
@@ -26184,3 +26270,51 @@ TEST(InternalFieldsOnDataView) {
array->GetAlignedPointerFromInternalField(i));
}
}
+
+TEST(SetPrototypeTemplate) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+
+ Local<FunctionTemplate> HTMLElementTemplate = FunctionTemplate::New(isolate);
+ Local<FunctionTemplate> HTMLImageElementTemplate =
+ FunctionTemplate::New(isolate);
+ HTMLImageElementTemplate->Inherit(HTMLElementTemplate);
+
+ Local<FunctionTemplate> ImageTemplate = FunctionTemplate::New(isolate);
+ ImageTemplate->SetPrototypeProviderTemplate(HTMLImageElementTemplate);
+
+ Local<Function> HTMLImageElement =
+ HTMLImageElementTemplate->GetFunction(env.local()).ToLocalChecked();
+ Local<Function> Image =
+ ImageTemplate->GetFunction(env.local()).ToLocalChecked();
+
+ CHECK(env->Global()
+ ->Set(env.local(), v8_str("HTMLImageElement"), HTMLImageElement)
+ .FromJust());
+ CHECK(env->Global()->Set(env.local(), v8_str("Image"), Image).FromJust());
+
+ ExpectTrue("Image.prototype === HTMLImageElement.prototype");
+}
+
+UNINITIALIZED_TEST(IncreaseHeapLimitForDebugging) {
+ using namespace i;
+ v8::Isolate::CreateParams create_params;
+ create_params.constraints.set_max_old_space_size(16);
+ create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
+ v8::Isolate* isolate = v8::Isolate::New(create_params);
+ Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate);
+ {
+ size_t limit_before = i_isolate->heap()->MaxOldGenerationSize();
+ CHECK_EQ(16 * MB, limit_before);
+ CHECK(!isolate->IsHeapLimitIncreasedForDebugging());
+ isolate->IncreaseHeapLimitForDebugging();
+ CHECK(isolate->IsHeapLimitIncreasedForDebugging());
+ size_t limit_after = i_isolate->heap()->MaxOldGenerationSize();
+ CHECK_EQ(4 * 16 * MB, limit_after);
+ isolate->RestoreOriginalHeapLimit();
+ CHECK(!isolate->IsHeapLimitIncreasedForDebugging());
+ CHECK_EQ(limit_before, i_isolate->heap()->MaxOldGenerationSize());
+ }
+ isolate->Dispose();
+}
diff --git a/deps/v8/test/cctest/test-assembler-arm.cc b/deps/v8/test/cctest/test-assembler-arm.cc
index 08f1f5a9f3..680b1233f7 100644
--- a/deps/v8/test/cctest/test-assembler-arm.cc
+++ b/deps/v8/test/cctest/test-assembler-arm.cc
@@ -1221,6 +1221,32 @@ TEST(14) {
CHECK_EQ(kArmNanLower32, bit_cast<int64_t>(t.div_result) & 0xffffffffu);
}
+#define CHECK_EQ_SPLAT(field, ex) \
+ CHECK_EQ(ex, t.field[0]); \
+ CHECK_EQ(ex, t.field[1]); \
+ CHECK_EQ(ex, t.field[2]); \
+ CHECK_EQ(ex, t.field[3]);
+
+#define CHECK_EQ_32X4(field, ex0, ex1, ex2, ex3) \
+ CHECK_EQ(ex0, t.field[0]); \
+ CHECK_EQ(ex1, t.field[1]); \
+ CHECK_EQ(ex2, t.field[2]); \
+ CHECK_EQ(ex3, t.field[3]);
+
+#define CHECK_ESTIMATE(expected, tolerance, value) \
+ CHECK_LT((expected) - (tolerance), value); \
+ CHECK_GT((expected) + (tolerance), value);
+
+#define CHECK_ESTIMATE_SPLAT(field, ex, tol) \
+ CHECK_ESTIMATE(ex, tol, t.field[0]); \
+ CHECK_ESTIMATE(ex, tol, t.field[1]); \
+ CHECK_ESTIMATE(ex, tol, t.field[2]); \
+ CHECK_ESTIMATE(ex, tol, t.field[3]);
+
+#define INT32_TO_FLOAT(val) \
+ std::round(static_cast<float>(bit_cast<int32_t>(val)))
+#define UINT32_TO_FLOAT(val) \
+ std::round(static_cast<float>(bit_cast<uint32_t>(val)))
TEST(15) {
// Test the Neon instructions.
@@ -1255,18 +1281,50 @@ TEST(15) {
uint32_t dstA5;
uint32_t dstA6;
uint32_t dstA7;
+ uint32_t lane_test[4];
+ uint64_t vmov_to_scalar1, vmov_to_scalar2;
+ uint32_t vmov_from_scalar_s8, vmov_from_scalar_u8;
+ uint32_t vmov_from_scalar_s16, vmov_from_scalar_u16;
+ uint32_t vmov_from_scalar_32;
+ uint32_t vmov[4], vmvn[4];
+ int32_t vcvt_s32_f32[4];
+ uint32_t vcvt_u32_f32[4];
+ float vcvt_f32_s32[4], vcvt_f32_u32[4];
+ uint32_t vdup8[4], vdup16[4], vdup32[4];
+ float vabsf[4], vnegf[4];
+ uint32_t vabs_s8[4], vabs_s16[4], vabs_s32[4];
+ uint32_t vneg_s8[4], vneg_s16[4], vneg_s32[4];
+ uint32_t veor[4], vand[4], vorr[4];
+ float vdupf[4], vaddf[4], vsubf[4], vmulf[4];
+ uint32_t vmin_s8[4], vmin_u16[4], vmin_s32[4];
+ uint32_t vmax_s8[4], vmax_u16[4], vmax_s32[4];
+ uint32_t vadd8[4], vadd16[4], vadd32[4];
+ uint32_t vsub8[4], vsub16[4], vsub32[4];
+ uint32_t vmul8[4], vmul16[4], vmul32[4];
+ uint32_t vceq[4], vceqf[4], vcgef[4], vcgtf[4];
+ uint32_t vcge_s8[4], vcge_u16[4], vcge_s32[4];
+ uint32_t vcgt_s8[4], vcgt_u16[4], vcgt_s32[4];
+ float vrecpe[4], vrecps[4], vrsqrte[4], vrsqrts[4];
+ float vminf[4], vmaxf[4];
+ uint32_t vtst[4], vbsl[4];
+ uint32_t vext[4];
+ uint32_t vzip8a[4], vzip8b[4], vzip16a[4], vzip16b[4], vzip32a[4],
+ vzip32b[4];
+ uint32_t vrev64_32[4], vrev64_16[4], vrev64_8[4];
+ uint32_t vrev32_16[4], vrev32_8[4];
+ uint32_t vrev16_8[4];
+ uint32_t vtbl[2], vtbx[2];
} T;
T t;
// Create a function that accepts &t, and loads, manipulates, and stores
- // the doubles and floats.
+ // the doubles, floats, and SIMD values.
Assembler assm(isolate, NULL, 0);
-
if (CpuFeatures::IsSupported(NEON)) {
CpuFeatureScope scope(&assm, NEON);
- __ stm(db_w, sp, r4.bit() | lr.bit());
+ __ stm(db_w, sp, r4.bit() | r5.bit() | lr.bit());
// Move 32 bytes with neon.
__ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, src0))));
__ vld1(Neon8, NeonListOperand(d0, 4), NeonMemOperand(r4));
@@ -1287,7 +1345,456 @@ TEST(15) {
__ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, dstA4))));
__ vst1(Neon8, NeonListOperand(d2, 2), NeonMemOperand(r4));
- __ ldm(ia_w, sp, r4.bit() | pc.bit());
+ // ARM core register to scalar.
+ __ mov(r4, Operand(0xfffffff8));
+ __ vmov(d0, 0);
+ __ vmov(NeonS8, d0, 1, r4);
+ __ vmov(NeonS16, d0, 1, r4);
+ __ vmov(NeonS32, d0, 1, r4);
+ __ vstr(d0, r0, offsetof(T, vmov_to_scalar1));
+ __ vmov(d0, 0);
+ __ vmov(NeonS8, d0, 3, r4);
+ __ vmov(NeonS16, d0, 3, r4);
+ __ vstr(d0, r0, offsetof(T, vmov_to_scalar2));
+
+ // Scalar to ARM core register.
+ __ mov(r4, Operand(0xffffff00));
+ __ mov(r5, Operand(0xffffffff));
+ __ vmov(d0, r4, r5);
+ __ vmov(NeonS8, r4, d0, 1);
+ __ str(r4, MemOperand(r0, offsetof(T, vmov_from_scalar_s8)));
+ __ vmov(NeonU8, r4, d0, 1);
+ __ str(r4, MemOperand(r0, offsetof(T, vmov_from_scalar_u8)));
+ __ vmov(NeonS16, r4, d0, 1);
+ __ str(r4, MemOperand(r0, offsetof(T, vmov_from_scalar_s16)));
+ __ vmov(NeonU16, r4, d0, 1);
+ __ str(r4, MemOperand(r0, offsetof(T, vmov_from_scalar_u16)));
+ __ vmov(NeonS32, r4, d0, 1);
+ __ str(r4, MemOperand(r0, offsetof(T, vmov_from_scalar_32)));
+
+ // vmov for q-registers.
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, lane_test))));
+ __ vld1(Neon8, NeonListOperand(q0), NeonMemOperand(r4));
+ __ vmov(q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vmov))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+
+ // vmvn.
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, lane_test))));
+ __ vld1(Neon8, NeonListOperand(q0), NeonMemOperand(r4));
+ __ vmvn(q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vmvn))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+
+ // vcvt for q-registers.
+ __ vmov(s0, -1.5);
+ __ vmov(s1, -1);
+ __ vmov(s2, 1);
+ __ vmov(s3, 1.5);
+ __ vcvt_s32_f32(q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vcvt_s32_f32))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ __ vcvt_u32_f32(q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vcvt_u32_f32))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ __ mov(r4, Operand(kMinInt));
+ __ mov(r5, Operand(kMaxInt));
+ __ vmov(d0, r4, r5);
+ __ mov(r4, Operand(kMaxUInt32));
+ __ mov(r5, Operand(kMinInt + 1));
+ __ vmov(d1, r4, r5); // q0 = [kMinInt, kMaxInt, kMaxUInt32, kMinInt + 1]
+ __ vcvt_f32_s32(q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vcvt_f32_s32))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ __ vcvt_f32_u32(q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vcvt_f32_u32))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+
+ // vdup (integer).
+ __ mov(r4, Operand(0xa));
+ __ vdup(Neon8, q0, r4);
+ __ vdup(Neon16, q1, r4);
+ __ vdup(Neon32, q2, r4);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vdup8))));
+ __ vst1(Neon8, NeonListOperand(q0), NeonMemOperand(r4));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vdup16))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vdup32))));
+ __ vst1(Neon8, NeonListOperand(q2), NeonMemOperand(r4));
+
+ // vdup (float).
+ __ vmov(s0, -1.0);
+ __ vdup(q0, s0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vdupf))));
+ __ vst1(Neon8, NeonListOperand(q0), NeonMemOperand(r4));
+
+ // vabs (float).
+ __ vmov(s0, -1.0);
+ __ vmov(s1, -0.0);
+ __ vmov(s2, 0.0);
+ __ vmov(s3, 1.0);
+ __ vabs(q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vabsf))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ // vneg (float).
+ __ vneg(q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vnegf))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+
+ // vabs (integer).
+ __ mov(r4, Operand(0x7f7f7f7f));
+ __ mov(r5, Operand(0x01010101));
+ __ vmov(d0, r4, r5);
+ __ mov(r4, Operand(0xffffffff));
+ __ mov(r5, Operand(0x80808080));
+ __ vmov(d1, r4, r5);
+ __ vabs(Neon8, q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vabs_s8))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ __ vabs(Neon16, q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vabs_s16))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ __ vabs(Neon32, q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vabs_s32))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ // vneg (integer).
+ __ vneg(Neon8, q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vneg_s8))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ __ vneg(Neon16, q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vneg_s16))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ __ vneg(Neon32, q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vneg_s32))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+
+ // veor.
+ __ mov(r4, Operand(0xaa));
+ __ vdup(Neon16, q0, r4);
+ __ mov(r4, Operand(0x55));
+ __ vdup(Neon16, q1, r4);
+ __ veor(q1, q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, veor))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ // vand.
+ __ mov(r4, Operand(0xff));
+ __ vdup(Neon16, q0, r4);
+ __ mov(r4, Operand(0xfe));
+ __ vdup(Neon16, q1, r4);
+ __ vand(q1, q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vand))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ // vorr.
+ __ mov(r4, Operand(0xaa));
+ __ vdup(Neon16, q0, r4);
+ __ mov(r4, Operand(0x55));
+ __ vdup(Neon16, q1, r4);
+ __ vorr(q1, q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vorr))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+
+ // vmin (float).
+ __ vmov(s4, 2.0);
+ __ vdup(q0, s4);
+ __ vmov(s4, 1.0);
+ __ vdup(q1, s4);
+ __ vmin(q1, q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vminf))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ // vmax (float).
+ __ vmov(s4, 2.0);
+ __ vdup(q0, s4);
+ __ vmov(s4, 1.0);
+ __ vdup(q1, s4);
+ __ vmax(q1, q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vmaxf))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ // vadd (float).
+ __ vmov(s4, 1.0);
+ __ vdup(q0, s4);
+ __ vdup(q1, s4);
+ __ vadd(q1, q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vaddf))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ // vsub (float).
+ __ vmov(s4, 2.0);
+ __ vdup(q0, s4);
+ __ vmov(s4, 1.0);
+ __ vdup(q1, s4);
+ __ vsub(q1, q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vsubf))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ // vmul (float).
+ __ vmov(s4, 2.0);
+ __ vdup(q0, s4);
+ __ vdup(q1, s4);
+ __ vmul(q1, q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vmulf))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ // vrecpe.
+ __ vmov(s4, 2.0);
+ __ vdup(q0, s4);
+ __ vrecpe(q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vrecpe))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ // vrecps.
+ __ vmov(s4, 2.0);
+ __ vdup(q0, s4);
+ __ vmov(s4, 1.5);
+ __ vdup(q1, s4);
+ __ vrecps(q1, q0, q1);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vrecps))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ // vrsqrte.
+ __ vmov(s4, 4.0);
+ __ vdup(q0, s4);
+ __ vrsqrte(q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vrsqrte))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ // vrsqrts.
+ __ vmov(s4, 2.0);
+ __ vdup(q0, s4);
+ __ vmov(s4, 2.5);
+ __ vdup(q1, s4);
+ __ vrsqrts(q1, q0, q1);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vrsqrts))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ // vceq (float).
+ __ vmov(s4, 1.0);
+ __ vdup(q0, s4);
+ __ vdup(q1, s4);
+ __ vceq(q1, q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vceqf))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ // vcge (float).
+ __ vmov(s0, 1.0);
+ __ vmov(s1, -1.0);
+ __ vmov(s2, -0.0);
+ __ vmov(s3, 0.0);
+ __ vdup(q1, s3);
+ __ vcge(q2, q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vcgef))));
+ __ vst1(Neon8, NeonListOperand(q2), NeonMemOperand(r4));
+ __ vcgt(q2, q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vcgtf))));
+ __ vst1(Neon8, NeonListOperand(q2), NeonMemOperand(r4));
+
+ // vmin/vmax integer.
+ __ mov(r4, Operand(0x03));
+ __ vdup(Neon16, q0, r4);
+ __ vdup(Neon8, q1, r4);
+ __ vmin(NeonS8, q2, q0, q1);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vmin_s8))));
+ __ vst1(Neon8, NeonListOperand(q2), NeonMemOperand(r4));
+ __ vmax(NeonS8, q2, q0, q1);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vmax_s8))));
+ __ vst1(Neon8, NeonListOperand(q2), NeonMemOperand(r4));
+ __ mov(r4, Operand(0xff));
+ __ vdup(Neon16, q0, r4);
+ __ vdup(Neon8, q1, r4);
+ __ vmin(NeonU16, q2, q0, q1);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vmin_u16))));
+ __ vst1(Neon8, NeonListOperand(q2), NeonMemOperand(r4));
+ __ vmax(NeonU16, q2, q0, q1);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vmax_u16))));
+ __ vst1(Neon8, NeonListOperand(q2), NeonMemOperand(r4));
+ __ mov(r4, Operand(0xff));
+ __ vdup(Neon32, q0, r4);
+ __ vdup(Neon8, q1, r4);
+ __ vmin(NeonS32, q2, q0, q1);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vmin_s32))));
+ __ vst1(Neon8, NeonListOperand(q2), NeonMemOperand(r4));
+ __ vmax(NeonS32, q2, q0, q1);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vmax_s32))));
+ __ vst1(Neon8, NeonListOperand(q2), NeonMemOperand(r4));
+
+ // vadd (integer).
+ __ mov(r4, Operand(0x81));
+ __ vdup(Neon8, q0, r4);
+ __ mov(r4, Operand(0x82));
+ __ vdup(Neon8, q1, r4);
+ __ vadd(Neon8, q1, q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vadd8))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ __ mov(r4, Operand(0x8001));
+ __ vdup(Neon16, q0, r4);
+ __ mov(r4, Operand(0x8002));
+ __ vdup(Neon16, q1, r4);
+ __ vadd(Neon16, q1, q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vadd16))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ __ mov(r4, Operand(0x80000001));
+ __ vdup(Neon32, q0, r4);
+ __ mov(r4, Operand(0x80000002));
+ __ vdup(Neon32, q1, r4);
+ __ vadd(Neon32, q1, q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vadd32))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+
+ // vsub (integer).
+ __ mov(r4, Operand(0x01));
+ __ vdup(Neon8, q0, r4);
+ __ mov(r4, Operand(0x03));
+ __ vdup(Neon8, q1, r4);
+ __ vsub(Neon8, q1, q0, q1);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vsub8))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ __ mov(r4, Operand(0x0001));
+ __ vdup(Neon16, q0, r4);
+ __ mov(r4, Operand(0x0003));
+ __ vdup(Neon16, q1, r4);
+ __ vsub(Neon16, q1, q0, q1);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vsub16))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ __ mov(r4, Operand(0x00000001));
+ __ vdup(Neon32, q0, r4);
+ __ mov(r4, Operand(0x00000003));
+ __ vdup(Neon32, q1, r4);
+ __ vsub(Neon32, q1, q0, q1);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vsub32))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+
+ // vmul (integer).
+ __ mov(r4, Operand(0x02));
+ __ vdup(Neon8, q0, r4);
+ __ vmul(Neon8, q1, q0, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vmul8))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ __ mov(r4, Operand(0x0002));
+ __ vdup(Neon16, q0, r4);
+ __ vmul(Neon16, q1, q0, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vmul16))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ __ mov(r4, Operand(0x00000002));
+ __ vdup(Neon32, q0, r4);
+ __ vmul(Neon32, q1, q0, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vmul32))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+
+ // vceq.
+ __ mov(r4, Operand(0x03));
+ __ vdup(Neon8, q0, r4);
+ __ vdup(Neon16, q1, r4);
+ __ vceq(Neon8, q1, q0, q1);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vceq))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+
+ // vcge/vcgt (integer).
+ __ mov(r4, Operand(0x03));
+ __ vdup(Neon16, q0, r4);
+ __ vdup(Neon8, q1, r4);
+ __ vcge(NeonS8, q2, q0, q1);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vcge_s8))));
+ __ vst1(Neon8, NeonListOperand(q2), NeonMemOperand(r4));
+ __ vcgt(NeonS8, q2, q0, q1);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vcgt_s8))));
+ __ vst1(Neon8, NeonListOperand(q2), NeonMemOperand(r4));
+ __ mov(r4, Operand(0xff));
+ __ vdup(Neon16, q0, r4);
+ __ vdup(Neon8, q1, r4);
+ __ vcge(NeonU16, q2, q0, q1);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vcge_u16))));
+ __ vst1(Neon8, NeonListOperand(q2), NeonMemOperand(r4));
+ __ vcgt(NeonU16, q2, q0, q1);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vcgt_u16))));
+ __ vst1(Neon8, NeonListOperand(q2), NeonMemOperand(r4));
+ __ mov(r4, Operand(0xff));
+ __ vdup(Neon32, q0, r4);
+ __ vdup(Neon8, q1, r4);
+ __ vcge(NeonS32, q2, q0, q1);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vcge_s32))));
+ __ vst1(Neon8, NeonListOperand(q2), NeonMemOperand(r4));
+ __ vcgt(NeonS32, q2, q0, q1);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vcgt_s32))));
+ __ vst1(Neon8, NeonListOperand(q2), NeonMemOperand(r4));
+
+ // vtst.
+ __ mov(r4, Operand(0x03));
+ __ vdup(Neon8, q0, r4);
+ __ mov(r4, Operand(0x02));
+ __ vdup(Neon16, q1, r4);
+ __ vtst(Neon8, q1, q0, q1);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vtst))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+
+ // vbsl.
+ __ mov(r4, Operand(0x00ff));
+ __ vdup(Neon16, q0, r4);
+ __ mov(r4, Operand(0x01));
+ __ vdup(Neon8, q1, r4);
+ __ mov(r4, Operand(0x02));
+ __ vdup(Neon8, q2, r4);
+ __ vbsl(q0, q1, q2);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vbsl))));
+ __ vst1(Neon8, NeonListOperand(q0), NeonMemOperand(r4));
+
+ // vext.
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, lane_test))));
+ __ vld1(Neon8, NeonListOperand(q0), NeonMemOperand(r4));
+ __ vmov(q1, q0);
+ __ vext(q2, q0, q1, 3);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vext))));
+ __ vst1(Neon8, NeonListOperand(q2), NeonMemOperand(r4));
+
+ // vzip.
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, lane_test))));
+ __ vld1(Neon8, NeonListOperand(q0), NeonMemOperand(r4));
+ __ vmov(q1, q0);
+ __ vzip(Neon8, q0, q1);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vzip8a))));
+ __ vst1(Neon8, NeonListOperand(q0), NeonMemOperand(r4));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vzip8b))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, lane_test))));
+ __ vld1(Neon8, NeonListOperand(q0), NeonMemOperand(r4));
+ __ vmov(q1, q0);
+ __ vzip(Neon16, q0, q1);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vzip16a))));
+ __ vst1(Neon8, NeonListOperand(q0), NeonMemOperand(r4));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vzip16b))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, lane_test))));
+ __ vld1(Neon8, NeonListOperand(q0), NeonMemOperand(r4));
+ __ vmov(q1, q0);
+ __ vzip(Neon32, q0, q1);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vzip32a))));
+ __ vst1(Neon8, NeonListOperand(q0), NeonMemOperand(r4));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vzip32b))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+
+ // vrev64/32/16
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, lane_test))));
+ __ vld1(Neon8, NeonListOperand(q0), NeonMemOperand(r4));
+ __ vrev64(Neon32, q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vrev64_32))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ __ vrev64(Neon16, q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vrev64_16))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ __ vrev64(Neon8, q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vrev64_8))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ __ vrev32(Neon16, q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vrev32_16))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ __ vrev32(Neon8, q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vrev32_8))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+ __ vrev16(Neon8, q1, q0);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, vrev16_8))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+
+ // vtb[l/x].
+ __ mov(r4, Operand(0x06040200));
+ __ mov(r5, Operand(0xff050301));
+ __ vmov(d2, r4, r5); // d2 = ff05030106040200
+ __ vtbl(d0, NeonListOperand(d2, 1), d2);
+ __ vstr(d0, r0, offsetof(T, vtbl));
+ __ vtbx(d2, NeonListOperand(d2, 1), d2);
+ __ vstr(d2, r0, offsetof(T, vtbx));
+
+ // Restore and return.
+ __ ldm(ia_w, sp, r4.bit() | r5.bit() | pc.bit());
CodeDesc desc;
assm.GetCode(&desc);
@@ -1324,8 +1831,13 @@ TEST(15) {
t.dstA5 = 0;
t.dstA6 = 0;
t.dstA7 = 0;
+ t.lane_test[0] = 0x03020100;
+ t.lane_test[1] = 0x07060504;
+ t.lane_test[2] = 0x0b0a0908;
+ t.lane_test[3] = 0x0f0e0d0c;
Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0);
USE(dummy);
+
CHECK_EQ(0x01020304u, t.dst0);
CHECK_EQ(0x11121314u, t.dst1);
CHECK_EQ(0x21222324u, t.dst2);
@@ -1342,10 +1854,118 @@ TEST(15) {
CHECK_EQ(0x00410042u, t.dstA5);
CHECK_EQ(0x00830084u, t.dstA6);
CHECK_EQ(0x00810082u, t.dstA7);
+
+ CHECK_EQ(0xfffffff8fff8f800u, t.vmov_to_scalar1);
+ CHECK_EQ(0xfff80000f8000000u, t.vmov_to_scalar2);
+ CHECK_EQ(0xFFFFFFFFu, t.vmov_from_scalar_s8);
+ CHECK_EQ(0xFFu, t.vmov_from_scalar_u8);
+ CHECK_EQ(0xFFFFFFFFu, t.vmov_from_scalar_s16);
+ CHECK_EQ(0xFFFFu, t.vmov_from_scalar_u16);
+ CHECK_EQ(0xFFFFFFFFu, t.vmov_from_scalar_32);
+
+ CHECK_EQ_32X4(vmov, 0x03020100u, 0x07060504u, 0x0b0a0908u, 0x0f0e0d0cu);
+ CHECK_EQ_32X4(vmvn, 0xfcfdfeffu, 0xf8f9fafbu, 0xf4f5f6f7u, 0xf0f1f2f3u);
+
+ CHECK_EQ_SPLAT(vdup8, 0x0a0a0a0au);
+ CHECK_EQ_SPLAT(vdup16, 0x000a000au);
+ CHECK_EQ_SPLAT(vdup32, 0x0000000au);
+ CHECK_EQ_SPLAT(vdupf, -1.0);
+
+ // src: [-1, -1, 1, 1]
+ CHECK_EQ_32X4(vcvt_s32_f32, -1, -1, 1, 1);
+ CHECK_EQ_32X4(vcvt_u32_f32, 0u, 0u, 1u, 1u);
+ // src: [kMinInt, kMaxInt, kMaxUInt32, kMinInt + 1]
+ CHECK_EQ_32X4(vcvt_f32_s32, INT32_TO_FLOAT(kMinInt),
+ INT32_TO_FLOAT(kMaxInt), INT32_TO_FLOAT(kMaxUInt32),
+ INT32_TO_FLOAT(kMinInt + 1));
+ CHECK_EQ_32X4(vcvt_f32_u32, UINT32_TO_FLOAT(kMinInt),
+ UINT32_TO_FLOAT(kMaxInt), UINT32_TO_FLOAT(kMaxUInt32),
+ UINT32_TO_FLOAT(kMinInt + 1));
+
+ CHECK_EQ_32X4(vabsf, 1.0, 0.0, 0.0, 1.0);
+ CHECK_EQ_32X4(vnegf, 1.0, 0.0, -0.0, -1.0);
+ // src: [0x7f7f7f7f, 0x01010101, 0xffffffff, 0x80808080]
+ CHECK_EQ_32X4(vabs_s8, 0x7f7f7f7fu, 0x01010101u, 0x01010101u, 0x80808080u);
+ CHECK_EQ_32X4(vabs_s16, 0x7f7f7f7fu, 0x01010101u, 0x00010001u, 0x7f807f80u);
+ CHECK_EQ_32X4(vabs_s32, 0x7f7f7f7fu, 0x01010101u, 0x00000001u, 0x7f7f7f80u);
+ CHECK_EQ_32X4(vneg_s8, 0x81818181u, 0xffffffffu, 0x01010101u, 0x80808080u);
+ CHECK_EQ_32X4(vneg_s16, 0x80818081u, 0xfefffeffu, 0x00010001u, 0x7f807f80u);
+ CHECK_EQ_32X4(vneg_s32, 0x80808081u, 0xfefefeffu, 0x00000001u, 0x7f7f7f80u);
+
+ CHECK_EQ_SPLAT(veor, 0x00ff00ffu);
+ CHECK_EQ_SPLAT(vand, 0x00fe00feu);
+ CHECK_EQ_SPLAT(vorr, 0x00ff00ffu);
+ CHECK_EQ_SPLAT(vaddf, 2.0);
+ CHECK_EQ_SPLAT(vminf, 1.0);
+ CHECK_EQ_SPLAT(vmaxf, 2.0);
+ CHECK_EQ_SPLAT(vsubf, -1.0);
+ CHECK_EQ_SPLAT(vmulf, 4.0);
+ CHECK_ESTIMATE_SPLAT(vrecpe, 0.5f, 0.1f); // 1 / 2
+ CHECK_EQ_SPLAT(vrecps, -1.0f); // 2 - (2 * 1.5)
+ CHECK_ESTIMATE_SPLAT(vrsqrte, 0.5f, 0.1f); // 1 / sqrt(4)
+ CHECK_EQ_SPLAT(vrsqrts, -1.0f); // (3 - (2 * 2.5)) / 2
+ CHECK_EQ_SPLAT(vceqf, 0xffffffffu);
+ // [0] >= [-1, 1, -0, 0]
+ CHECK_EQ_32X4(vcgef, 0u, 0xffffffffu, 0xffffffffu, 0xffffffffu);
+ CHECK_EQ_32X4(vcgtf, 0u, 0xffffffffu, 0u, 0u);
+ // [0, 3, 0, 3, ...] and [3, 3, 3, 3, ...]
+ CHECK_EQ_SPLAT(vmin_s8, 0x00030003u);
+ CHECK_EQ_SPLAT(vmax_s8, 0x03030303u);
+ // [0x00ff, 0x00ff, ...] and [0xffff, 0xffff, ...]
+ CHECK_EQ_SPLAT(vmin_u16, 0x00ff00ffu);
+ CHECK_EQ_SPLAT(vmax_u16, 0xffffffffu);
+ // [0x000000ff, 0x000000ff, ...] and [0xffffffff, 0xffffffff, ...]
+ CHECK_EQ_SPLAT(vmin_s32, 0xffffffffu);
+ CHECK_EQ_SPLAT(vmax_s32, 0xffu);
+ CHECK_EQ_SPLAT(vadd8, 0x03030303u);
+ CHECK_EQ_SPLAT(vadd16, 0x00030003u);
+ CHECK_EQ_SPLAT(vadd32, 0x00000003u);
+ CHECK_EQ_SPLAT(vsub8, 0xfefefefeu);
+ CHECK_EQ_SPLAT(vsub16, 0xfffefffeu);
+ CHECK_EQ_SPLAT(vsub32, 0xfffffffeu);
+ CHECK_EQ_SPLAT(vmul8, 0x04040404u);
+ CHECK_EQ_SPLAT(vmul16, 0x00040004u);
+ CHECK_EQ_SPLAT(vmul32, 0x00000004u);
+ CHECK_EQ_SPLAT(vceq, 0x00ff00ffu);
+ // [0, 3, 0, 3, ...] >= [3, 3, 3, 3, ...]
+ CHECK_EQ_SPLAT(vcge_s8, 0x00ff00ffu);
+ CHECK_EQ_SPLAT(vcgt_s8, 0u);
+ // [0x00ff, 0x00ff, ...] >= [0xffff, 0xffff, ...]
+ CHECK_EQ_SPLAT(vcge_u16, 0u);
+ CHECK_EQ_SPLAT(vcgt_u16, 0u);
+ // [0x000000ff, 0x000000ff, ...] >= [0xffffffff, 0xffffffff, ...]
+ CHECK_EQ_SPLAT(vcge_s32, 0xffffffffu);
+ CHECK_EQ_SPLAT(vcgt_s32, 0xffffffffu);
+ CHECK_EQ_SPLAT(vtst, 0x00ff00ffu);
+ CHECK_EQ_SPLAT(vbsl, 0x02010201u);
+
+ CHECK_EQ_32X4(vext, 0x06050403u, 0x0a090807u, 0x0e0d0c0bu, 0x0201000fu);
+
+ CHECK_EQ_32X4(vzip8a, 0x01010000u, 0x03030202u, 0x05050404u, 0x07070606u);
+ CHECK_EQ_32X4(vzip8b, 0x09090808u, 0x0b0b0a0au, 0x0d0d0c0cu, 0x0f0f0e0eu);
+ CHECK_EQ_32X4(vzip16a, 0x01000100u, 0x03020302u, 0x05040504u, 0x07060706u);
+ CHECK_EQ_32X4(vzip16b, 0x09080908u, 0x0b0a0b0au, 0x0d0c0d0cu, 0x0f0e0f0eu);
+ CHECK_EQ_32X4(vzip32a, 0x03020100u, 0x03020100u, 0x07060504u, 0x07060504u);
+ CHECK_EQ_32X4(vzip32b, 0x0b0a0908u, 0x0b0a0908u, 0x0f0e0d0cu, 0x0f0e0d0cu);
+
+ // src: 0 1 2 3 4 5 6 7 8 9 a b c d e f (little endian)
+ CHECK_EQ_32X4(vrev64_32, 0x07060504u, 0x03020100u, 0x0f0e0d0cu,
+ 0x0b0a0908u);
+ CHECK_EQ_32X4(vrev64_16, 0x05040706u, 0x01000302u, 0x0d0c0f0eu,
+ 0x09080b0au);
+ CHECK_EQ_32X4(vrev64_8, 0x04050607u, 0x00010203u, 0x0c0d0e0fu, 0x08090a0bu);
+ CHECK_EQ_32X4(vrev32_16, 0x01000302u, 0x05040706u, 0x09080b0au,
+ 0x0d0c0f0eu);
+ CHECK_EQ_32X4(vrev32_8, 0x00010203u, 0x04050607u, 0x08090a0bu, 0x0c0d0e0fu);
+ CHECK_EQ_32X4(vrev16_8, 0x02030001u, 0x06070405u, 0x0a0b0809u, 0x0e0f0c0du);
+
+ CHECK_EQ(0x05010400u, t.vtbl[0]);
+ CHECK_EQ(0x00030602u, t.vtbl[1]);
+ CHECK_EQ(0x05010400u, t.vtbx[0]);
+ CHECK_EQ(0xff030602u, t.vtbx[1]);
}
}
-
TEST(16) {
// Test the pkh, uxtb, uxtab and uxtb16 instructions.
CcTest::InitializeVM();
@@ -2881,33 +3501,63 @@ TEST(unaligned_stores) {
}
TEST(vswp) {
+ if (!CpuFeatures::IsSupported(NEON)) return;
+
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
Assembler assm(isolate, NULL, 0);
typedef struct {
- double result0;
- double result1;
- double result2;
- double result3;
+ uint64_t vswp_d0;
+ uint64_t vswp_d1;
+ uint64_t vswp_d30;
+ uint64_t vswp_d31;
+ uint32_t vswp_q4[4];
+ uint32_t vswp_q5[4];
} T;
T t;
- __ vmov(d0, 1.0);
- __ vmov(d1, -1.0);
+ __ stm(db_w, sp, r4.bit() | r5.bit() | r6.bit() | r7.bit() | lr.bit());
+
+ uint64_t one = bit_cast<uint64_t>(1.0);
+ __ mov(r5, Operand(one >> 32));
+ __ mov(r4, Operand(one & 0xffffffff));
+ uint64_t minus_one = bit_cast<uint64_t>(-1.0);
+ __ mov(r7, Operand(minus_one >> 32));
+ __ mov(r6, Operand(minus_one & 0xffffffff));
+
+ __ vmov(d0, r4, r5); // d0 = 1.0
+ __ vmov(d1, r6, r7); // d1 = -1.0
__ vswp(d0, d1);
- __ vstr(d0, r0, offsetof(T, result0));
- __ vstr(d1, r0, offsetof(T, result1));
+ __ vstr(d0, r0, offsetof(T, vswp_d0));
+ __ vstr(d1, r0, offsetof(T, vswp_d1));
if (CpuFeatures::IsSupported(VFP32DREGS)) {
- __ vmov(d30, 1.0);
- __ vmov(d31, -1.0);
+ __ vmov(d30, r4, r5); // d30 = 1.0
+ __ vmov(d31, r6, r7); // d31 = -1.0
__ vswp(d30, d31);
- __ vstr(d30, r0, offsetof(T, result2));
- __ vstr(d31, r0, offsetof(T, result3));
+ __ vstr(d30, r0, offsetof(T, vswp_d30));
+ __ vstr(d31, r0, offsetof(T, vswp_d31));
}
+ // q-register swap.
+ const uint32_t test_1 = 0x01234567;
+ const uint32_t test_2 = 0x89abcdef;
+ __ mov(r4, Operand(test_1));
+ __ mov(r5, Operand(test_2));
+ // TODO(bbudge) replace with vdup when implemented.
+ __ vmov(d8, r4, r4);
+ __ vmov(d9, r4, r4); // q4 = [1.0, 1.0]
+ __ vmov(d10, r5, r5);
+ __ vmov(d11, r5, r5); // q5 = [-1.0, -1.0]
+ __ vswp(q4, q5);
+ __ add(r6, r0, Operand(static_cast<int32_t>(offsetof(T, vswp_q4))));
+ __ vst1(Neon8, NeonListOperand(q4), NeonMemOperand(r6));
+ __ add(r6, r0, Operand(static_cast<int32_t>(offsetof(T, vswp_q5))));
+ __ vst1(Neon8, NeonListOperand(q5), NeonMemOperand(r6));
+
+ __ ldm(ia_w, sp, r4.bit() | r5.bit() | r6.bit() | r7.bit() | pc.bit());
__ bx(lr);
CodeDesc desc;
@@ -2921,12 +3571,20 @@ TEST(vswp) {
F3 f = FUNCTION_CAST<F3>(code->entry());
Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0);
USE(dummy);
- CHECK_EQ(-1.0, t.result0);
- CHECK_EQ(1.0, t.result1);
+ CHECK_EQ(minus_one, t.vswp_d0);
+ CHECK_EQ(one, t.vswp_d1);
if (CpuFeatures::IsSupported(VFP32DREGS)) {
- CHECK_EQ(-1.0, t.result2);
- CHECK_EQ(1.0, t.result3);
+ CHECK_EQ(minus_one, t.vswp_d30);
+ CHECK_EQ(one, t.vswp_d31);
}
+ CHECK_EQ(t.vswp_q4[0], test_2);
+ CHECK_EQ(t.vswp_q4[1], test_2);
+ CHECK_EQ(t.vswp_q4[2], test_2);
+ CHECK_EQ(t.vswp_q4[3], test_2);
+ CHECK_EQ(t.vswp_q5[0], test_1);
+ CHECK_EQ(t.vswp_q5[1], test_1);
+ CHECK_EQ(t.vswp_q5[2], test_1);
+ CHECK_EQ(t.vswp_q5[3], test_1);
}
TEST(regress4292_b) {
diff --git a/deps/v8/test/cctest/test-assembler-mips.cc b/deps/v8/test/cctest/test-assembler-mips.cc
index 08d3c606c0..191589a73a 100644
--- a/deps/v8/test/cctest/test-assembler-mips.cc
+++ b/deps/v8/test/cctest/test-assembler-mips.cc
@@ -5457,12 +5457,14 @@ void helper_madd_msub_maddf_msubf(F func) {
(CALL_GENERATED_CODE(isolate, f, &tc, 0, 0, 0, 0));
- T res_add = tc.fr + (tc.fs * tc.ft);
+ T res_add = 0;
T res_sub = 0;
if (IsMipsArchVariant(kMips32r2)) {
+ res_add = (tc.fs * tc.ft) + tc.fr;
res_sub = (tc.fs * tc.ft) - tc.fr;
} else if (IsMipsArchVariant(kMips32r6)) {
- res_sub = tc.fr - (tc.fs * tc.ft);
+ res_add = std::fma(tc.fs, tc.ft, tc.fr);
+ res_sub = std::fma(-tc.fs, tc.ft, tc.fr);
} else {
UNREACHABLE();
}
diff --git a/deps/v8/test/cctest/test-assembler-mips64.cc b/deps/v8/test/cctest/test-assembler-mips64.cc
index b0315343b5..0ec51723e9 100644
--- a/deps/v8/test/cctest/test-assembler-mips64.cc
+++ b/deps/v8/test/cctest/test-assembler-mips64.cc
@@ -6005,12 +6005,14 @@ void helper_madd_msub_maddf_msubf(F func) {
(CALL_GENERATED_CODE(isolate, f, &tc, 0, 0, 0, 0));
- T res_add = tc.fr + (tc.fs * tc.ft);
T res_sub;
+ T res_add;
if (kArchVariant != kMips64r6) {
+ res_add = tc.fr + (tc.fs * tc.ft);
res_sub = (tc.fs * tc.ft) - tc.fr;
} else {
- res_sub = tc.fr - (tc.fs * tc.ft);
+ res_add = std::fma(tc.fs, tc.ft, tc.fr);
+ res_sub = std::fma(-tc.fs, tc.ft, tc.fr);
}
CHECK_EQ(tc.fd_add, res_add);
diff --git a/deps/v8/test/cctest/test-assembler-s390.cc b/deps/v8/test/cctest/test-assembler-s390.cc
index ab6796bf18..f6b79d4994 100644
--- a/deps/v8/test/cctest/test-assembler-s390.cc
+++ b/deps/v8/test/cctest/test-assembler-s390.cc
@@ -194,8 +194,8 @@ TEST(3) {
__ ay(r13, MemOperand(r1, r2, 123));
__ brc(Condition(14), Operand(123));
__ brc(Condition(14), Operand(-123));
- __ brcl(Condition(14), Operand(123), false);
- __ brcl(Condition(14), Operand(-123), false);
+ __ brcl(Condition(14), Operand(123));
+ __ brcl(Condition(14), Operand(-123));
__ iilf(r13, Operand(123456789));
__ iihf(r13, Operand(-123456789));
__ mvc(MemOperand(r0, 123), MemOperand(r4, 567), 89);
@@ -413,4 +413,89 @@ TEST(9) {
}
#endif
+// Test msrkc and msgrkc
+TEST(10) {
+ if (!CpuFeatures::IsSupported(MISC_INSTR_EXT2)) {
+ return;
+ }
+
+ ::printf("MISC_INSTR_EXT2 is enabled.\n");
+
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ Assembler assm(isolate, NULL, 0);
+
+ Label ok, failed;
+
+ { // test 1: msrkc
+ __ lgfi(r2, Operand(3));
+ __ lgfi(r3, Operand(4));
+ __ msrkc(r1, r2, r3); // 3 * 4
+ __ b(static_cast<Condition>(le | overflow), &failed); // test failed.
+ __ chi(r1, Operand(12));
+ __ bne(&failed); // test failed.
+
+ __ lgfi(r2, Operand(-3));
+ __ lgfi(r3, Operand(4));
+ __ msrkc(r1, r2, r3); // -3 * 4
+ __ b(static_cast<Condition>(ge | overflow), &failed); // test failed.
+ __ chi(r1, Operand(-12));
+ __ bne(&failed); // test failed.
+
+ __ iilf(r2, Operand(0x80000000));
+ __ lgfi(r3, Operand(-1));
+ __ msrkc(r1, r2, r3); // INT_MIN * -1
+ __ b(nooverflow, &failed); // test failed.
+ __ cfi(r1, Operand(0x80000000));
+ __ bne(&failed); // test failed.
+ }
+
+ { // test 1: msgrkc
+ __ lgfi(r2, Operand(3));
+ __ lgfi(r3, Operand(4));
+ __ msgrkc(r1, r2, r3); // 3 * 4
+ __ b(static_cast<Condition>(le | overflow), &failed); // test failed.
+ __ chi(r1, Operand(12));
+ __ bne(&failed); // test failed.
+
+ __ lgfi(r2, Operand(-3));
+ __ lgfi(r3, Operand(4));
+ __ msgrkc(r1, r2, r3); // -3 * 4
+ __ b(static_cast<Condition>(ge | overflow), &failed); // test failed.
+ __ chi(r1, Operand(-12));
+ __ bne(&failed); // test failed.
+
+ __ lgfi(r2, Operand::Zero());
+ __ iihf(r2, Operand(0x80000000));
+ __ lgfi(r3, Operand(-1));
+ __ msgrkc(r1, r2, r3); // INT_MIN * -1
+ __ b(nooverflow, &failed); // test failed.
+ __ cgr(r1, r2);
+ __ bne(&failed); // test failed.
+ }
+
+ __ bind(&ok);
+ __ lgfi(r2, Operand::Zero());
+ __ b(r14); // test done.
+
+ __ bind(&failed);
+ __ lgfi(r2, Operand(1));
+ __ b(r14);
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef DEBUG
+ code->Print();
+#endif
+ F2 f = FUNCTION_CAST<F2>(code->entry());
+ intptr_t res = reinterpret_cast<intptr_t>(
+ CALL_GENERATED_CODE(isolate, f, 3, 4, 0, 0, 0));
+ ::printf("f() = %" V8PRIxPTR "\n", res);
+ CHECK_EQ(0, static_cast<int>(res));
+}
+
#undef __
diff --git a/deps/v8/test/cctest/test-assembler-x64.cc b/deps/v8/test/cctest/test-assembler-x64.cc
index 36f1b30df9..0ea854d7fe 100644
--- a/deps/v8/test/cctest/test-assembler-x64.cc
+++ b/deps/v8/test/cctest/test-assembler-x64.cc
@@ -173,6 +173,22 @@ TEST(AssemblerX64CmpbOperation) {
CHECK_EQ(0, result);
}
+TEST(Regression684407) {
+ CcTest::InitializeVM();
+ // Allocate an executable page of memory.
+ size_t actual_size;
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
+ CHECK(buffer);
+ Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
+ Address before = assm.pc();
+ __ cmpl(Operand(arg1, 0),
+ Immediate(0, RelocInfo::WASM_MEMORY_SIZE_REFERENCE));
+ Address after = assm.pc();
+ size_t instruction_size = static_cast<size_t>(after - before);
+ // Check that the immediate is not encoded as uint8.
+ CHECK_LT(sizeof(uint32_t), instruction_size);
+}
TEST(AssemblerX64ImulOperation) {
CcTest::InitializeVM();
@@ -201,6 +217,173 @@ TEST(AssemblerX64ImulOperation) {
CHECK_EQ(-1, result);
}
+TEST(AssemblerX64testbwqOperation) {
+ CcTest::InitializeVM();
+ v8::HandleScope scope(CcTest::isolate());
+ // Allocate an executable page of memory.
+ size_t actual_size;
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
+ CHECK(buffer);
+ Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
+
+ __ pushq(rbx);
+ __ pushq(rdi);
+ __ pushq(rsi);
+ __ pushq(r12);
+ __ pushq(r13);
+ __ pushq(r14);
+ __ pushq(r15);
+
+ // Assemble a simple function that tests testb and testw
+ Label bad;
+ Label done;
+
+ // Test immediate testb and testw
+ __ movq(rax, Immediate(2));
+ __ movq(rbx, Immediate(4));
+ __ movq(rcx, Immediate(8));
+ __ movq(rdx, Immediate(16));
+ __ movq(rsi, Immediate(32));
+ __ movq(rdi, Immediate(64));
+ __ movq(r10, Immediate(128));
+ __ movq(r11, Immediate(0));
+ __ movq(r12, Immediate(0));
+ __ movq(r13, Immediate(0));
+ __ testb(rax, Immediate(2));
+ __ j(zero, &bad);
+ __ testb(rbx, Immediate(4));
+ __ j(zero, &bad);
+ __ testb(rcx, Immediate(8));
+ __ j(zero, &bad);
+ __ testb(rdx, Immediate(16));
+ __ j(zero, &bad);
+ __ testb(rsi, Immediate(32));
+ __ j(zero, &bad);
+ __ testb(rdi, Immediate(64));
+ __ j(zero, &bad);
+ __ testb(r10, Immediate(128));
+ __ j(zero, &bad);
+ __ testw(rax, Immediate(2));
+ __ j(zero, &bad);
+ __ testw(rbx, Immediate(4));
+ __ j(zero, &bad);
+ __ testw(rcx, Immediate(8));
+ __ j(zero, &bad);
+ __ testw(rdx, Immediate(16));
+ __ j(zero, &bad);
+ __ testw(rsi, Immediate(32));
+ __ j(zero, &bad);
+ __ testw(rdi, Immediate(64));
+ __ j(zero, &bad);
+ __ testw(r10, Immediate(128));
+ __ j(zero, &bad);
+
+ // Test reg, reg testb and testw
+ __ movq(rax, Immediate(2));
+ __ movq(rbx, Immediate(2));
+ __ testb(rax, rbx);
+ __ j(zero, &bad);
+ __ movq(rbx, Immediate(4));
+ __ movq(rax, Immediate(4));
+ __ testb(rbx, rax);
+ __ j(zero, &bad);
+ __ movq(rax, Immediate(8));
+ __ testb(rcx, rax);
+ __ j(zero, &bad);
+ __ movq(rax, Immediate(16));
+ __ testb(rdx, rax);
+ __ j(zero, &bad);
+ __ movq(rax, Immediate(32));
+ __ testb(rsi, rax);
+ __ j(zero, &bad);
+ __ movq(rax, Immediate(64));
+ __ testb(rdi, rax);
+ __ j(zero, &bad);
+ __ movq(rax, Immediate(128));
+ __ testb(r10, rax);
+ __ j(zero, &bad);
+ __ movq(rax, Immediate(2));
+ __ movq(rbx, Immediate(2));
+ __ testw(rax, rbx);
+ __ j(zero, &bad);
+ __ movq(rbx, Immediate(4));
+ __ movq(rax, Immediate(4));
+ __ testw(rbx, rax);
+ __ j(zero, &bad);
+ __ movq(rax, Immediate(8));
+ __ testw(rcx, rax);
+ __ j(zero, &bad);
+ __ movq(rax, Immediate(16));
+ __ testw(rdx, rax);
+ __ j(zero, &bad);
+ __ movq(rax, Immediate(32));
+ __ testw(rsi, rax);
+ __ j(zero, &bad);
+ __ movq(rax, Immediate(64));
+ __ testw(rdi, rax);
+ __ j(zero, &bad);
+ __ movq(rax, Immediate(128));
+ __ testw(r10, rax);
+ __ j(zero, &bad);
+
+ // Test diffrrent extended register coding combinations.
+ __ movq(rax, Immediate(5));
+ __ movq(r11, Immediate(5));
+ __ testb(r11, rax);
+ __ j(zero, &bad);
+ __ testb(rax, r11);
+ __ j(zero, &bad);
+ __ testw(r11, rax);
+ __ j(zero, &bad);
+ __ testw(rax, r11);
+ __ j(zero, &bad);
+ __ movq(r11, Immediate(3));
+ __ movq(r12, Immediate(3));
+ __ movq(rdi, Immediate(3));
+ __ testb(r12, rdi);
+ __ j(zero, &bad);
+ __ testb(rdi, r12);
+ __ j(zero, &bad);
+ __ testb(r12, r11);
+ __ j(zero, &bad);
+ __ testb(r11, r12);
+ __ j(zero, &bad);
+ __ testw(r12, r11);
+ __ j(zero, &bad);
+ __ testw(r11, r12);
+ __ j(zero, &bad);
+
+ // Test sign-extended imediate tests
+ __ movq(r11, Immediate(2));
+ __ shlq(r11, Immediate(32));
+ __ testq(r11, Immediate(-1));
+ __ j(zero, &bad);
+
+ // All tests passed
+ __ movq(rax, Immediate(1));
+ __ jmp(&done);
+
+ __ bind(&bad);
+ __ movq(rax, Immediate(0));
+ __ bind(&done);
+
+ __ popq(r15);
+ __ popq(r14);
+ __ popq(r13);
+ __ popq(r12);
+ __ popq(rsi);
+ __ popq(rdi);
+ __ popq(rbx);
+
+ __ ret(0);
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ // Call the function from C++.
+ int result = FUNCTION_CAST<F2>(buffer)(0, 0);
+ CHECK_EQ(1, result);
+}
TEST(AssemblerX64XchglOperations) {
CcTest::InitializeVM();
diff --git a/deps/v8/test/cctest/test-ast.cc b/deps/v8/test/cctest/test-ast.cc
index dfb4d11236..c027e88a52 100644
--- a/deps/v8/test/cctest/test-ast.cc
+++ b/deps/v8/test/cctest/test-ast.cc
@@ -30,18 +30,24 @@
#include "src/v8.h"
#include "src/ast/ast.h"
+#include "src/isolate.h"
+#include "src/objects-inl.h"
#include "src/zone/accounting-allocator.h"
#include "test/cctest/cctest.h"
using namespace v8::internal;
TEST(List) {
+ v8::V8::Initialize();
+ Isolate* isolate = CcTest::i_isolate();
+
List<AstNode*>* list = new List<AstNode*>(0);
CHECK_EQ(0, list->length());
v8::internal::AccountingAllocator allocator;
Zone zone(&allocator, ZONE_NAME);
- AstValueFactory value_factory(&zone, 0);
+ AstValueFactory value_factory(&zone, isolate->ast_string_constants(),
+ isolate->heap()->HashSeed());
AstNodeFactory factory(&value_factory);
AstNode* node = factory.NewEmptyStatement(kNoSourcePosition);
list->Add(node);
@@ -59,43 +65,3 @@ TEST(List) {
CHECK_EQ(0, list->length());
delete list;
}
-
-TEST(ConcatStrings) {
- v8::internal::AccountingAllocator allocator;
- Zone zone(&allocator, ZONE_NAME);
- AstValueFactory value_factory(&zone, 0);
-
- const AstRawString* one_byte = value_factory.GetOneByteString("a");
-
- uint16_t two_byte_buffer[] = {
- 0x3b1,
- };
- const AstRawString* two_byte = value_factory.GetTwoByteString(
- Vector<const uint16_t>(two_byte_buffer, 1));
-
- const AstRawString* expectation = value_factory.GetOneByteString("aa");
- const AstRawString* result = value_factory.ConcatStrings(one_byte, one_byte);
- CHECK(result->is_one_byte());
- CHECK_EQ(expectation, result);
-
- uint16_t expectation_buffer_one_two[] = {'a', 0x3b1};
- expectation = value_factory.GetTwoByteString(
- Vector<const uint16_t>(expectation_buffer_one_two, 2));
- result = value_factory.ConcatStrings(one_byte, two_byte);
- CHECK(!result->is_one_byte());
- CHECK_EQ(expectation, result);
-
- uint16_t expectation_buffer_two_one[] = {0x3b1, 'a'};
- expectation = value_factory.GetTwoByteString(
- Vector<const uint16_t>(expectation_buffer_two_one, 2));
- result = value_factory.ConcatStrings(two_byte, one_byte);
- CHECK(!result->is_one_byte());
- CHECK_EQ(expectation, result);
-
- uint16_t expectation_buffer_two_two[] = {0x3b1, 0x3b1};
- expectation = value_factory.GetTwoByteString(
- Vector<const uint16_t>(expectation_buffer_two_two, 2));
- result = value_factory.ConcatStrings(two_byte, two_byte);
- CHECK(!result->is_one_byte());
- CHECK_EQ(expectation, result);
-}
diff --git a/deps/v8/test/cctest/test-code-stub-assembler.cc b/deps/v8/test/cctest/test-code-stub-assembler.cc
index da2773fdca..068ef9c3d1 100644
--- a/deps/v8/test/cctest/test-code-stub-assembler.cc
+++ b/deps/v8/test/cctest/test-code-stub-assembler.cc
@@ -3,10 +3,10 @@
// found in the LICENSE file.
#include "src/base/utils/random-number-generator.h"
+#include "src/builtins/builtins-promise.h"
#include "src/code-factory.h"
#include "src/code-stub-assembler.h"
#include "src/compiler/node.h"
-#include "src/ic/stub-cache.h"
#include "src/isolate.h"
#include "test/cctest/compiler/code-assembler-tester.h"
#include "test/cctest/compiler/function-tester.h"
@@ -14,48 +14,49 @@
namespace v8 {
namespace internal {
+using compiler::CodeAssemblerTester;
using compiler::FunctionTester;
using compiler::Node;
-
-typedef compiler::CodeAssemblerTesterImpl<CodeStubAssembler>
- CodeStubAssemblerTester;
+using compiler::CodeAssemblerLabel;
+using compiler::CodeAssemblerVariable;
+using compiler::CodeAssemblerVariableList;
TEST(FixedArrayAccessSmiIndex) {
Isolate* isolate(CcTest::InitIsolateOnce());
- VoidDescriptor descriptor(isolate);
- CodeStubAssemblerTester m(isolate, descriptor);
+ CodeAssemblerTester data(isolate);
+ CodeStubAssembler m(data.state());
Handle<FixedArray> array = isolate->factory()->NewFixedArray(5);
array->set(4, Smi::FromInt(733));
m.Return(m.LoadFixedArrayElement(m.HeapConstant(array),
m.SmiTag(m.Int32Constant(4)), 0,
CodeStubAssembler::SMI_PARAMETERS));
- Handle<Code> code = m.GenerateCode();
- FunctionTester ft(descriptor, code);
+ Handle<Code> code = data.GenerateCode();
+ FunctionTester ft(code);
MaybeHandle<Object> result = ft.Call();
CHECK_EQ(733, Handle<Smi>::cast(result.ToHandleChecked())->value());
}
TEST(LoadHeapNumberValue) {
Isolate* isolate(CcTest::InitIsolateOnce());
- VoidDescriptor descriptor(isolate);
- CodeStubAssemblerTester m(isolate, descriptor);
+ CodeAssemblerTester data(isolate);
+ CodeStubAssembler m(data.state());
Handle<HeapNumber> number = isolate->factory()->NewHeapNumber(1234);
- m.Return(m.SmiTag(
+ m.Return(m.SmiFromWord32(
m.ChangeFloat64ToUint32(m.LoadHeapNumberValue(m.HeapConstant(number)))));
- Handle<Code> code = m.GenerateCode();
- FunctionTester ft(descriptor, code);
+ Handle<Code> code = data.GenerateCode();
+ FunctionTester ft(code);
MaybeHandle<Object> result = ft.Call();
CHECK_EQ(1234, Handle<Smi>::cast(result.ToHandleChecked())->value());
}
TEST(LoadInstanceType) {
Isolate* isolate(CcTest::InitIsolateOnce());
- VoidDescriptor descriptor(isolate);
- CodeStubAssemblerTester m(isolate, descriptor);
+ CodeAssemblerTester data(isolate);
+ CodeStubAssembler m(data.state());
Handle<HeapObject> undefined = isolate->factory()->undefined_value();
- m.Return(m.SmiTag(m.LoadInstanceType(m.HeapConstant(undefined))));
- Handle<Code> code = m.GenerateCode();
- FunctionTester ft(descriptor, code);
+ m.Return(m.SmiFromWord32(m.LoadInstanceType(m.HeapConstant(undefined))));
+ Handle<Code> code = data.GenerateCode();
+ FunctionTester ft(code);
MaybeHandle<Object> result = ft.Call();
CHECK_EQ(InstanceType::ODDBALL_TYPE,
Handle<Smi>::cast(result.ToHandleChecked())->value());
@@ -63,14 +64,14 @@ TEST(LoadInstanceType) {
TEST(DecodeWordFromWord32) {
Isolate* isolate(CcTest::InitIsolateOnce());
- VoidDescriptor descriptor(isolate);
- CodeStubAssemblerTester m(isolate, descriptor);
+ CodeAssemblerTester data(isolate);
+ CodeStubAssembler m(data.state());
class TestBitField : public BitField<unsigned, 3, 3> {};
m.Return(
m.SmiTag(m.DecodeWordFromWord32<TestBitField>(m.Int32Constant(0x2f))));
- Handle<Code> code = m.GenerateCode();
- FunctionTester ft(descriptor, code);
+ Handle<Code> code = data.GenerateCode();
+ FunctionTester ft(code);
MaybeHandle<Object> result = ft.Call();
// value = 00101111
// mask = 00111000
@@ -81,11 +82,12 @@ TEST(DecodeWordFromWord32) {
TEST(JSFunction) {
const int kNumParams = 3; // Receiver, left, right.
Isolate* isolate(CcTest::InitIsolateOnce());
- CodeStubAssemblerTester m(isolate, kNumParams);
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeStubAssembler m(data.state());
m.Return(m.SmiFromWord32(m.Int32Add(m.SmiToWord32(m.Parameter(1)),
m.SmiToWord32(m.Parameter(2)))));
- Handle<Code> code = m.GenerateCode();
+ Handle<Code> code = data.GenerateCode();
FunctionTester ft(code, kNumParams);
MaybeHandle<Object> result = ft.Call(isolate->factory()->undefined_value(),
@@ -97,11 +99,12 @@ TEST(JSFunction) {
TEST(ComputeIntegerHash) {
Isolate* isolate(CcTest::InitIsolateOnce());
const int kNumParams = 2;
- CodeStubAssemblerTester m(isolate, kNumParams);
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeStubAssembler m(data.state());
m.Return(m.SmiFromWord32(m.ComputeIntegerHash(
- m.SmiToWord32(m.Parameter(0)), m.SmiToWord32(m.Parameter(1)))));
+ m.SmiUntag(m.Parameter(0)), m.SmiToWord32(m.Parameter(1)))));
- Handle<Code> code = m.GenerateCode();
+ Handle<Code> code = data.GenerateCode();
FunctionTester ft(code, kNumParams);
Handle<Smi> hash_seed = isolate->factory()->hash_seed();
@@ -123,10 +126,11 @@ TEST(ComputeIntegerHash) {
TEST(ToString) {
Isolate* isolate(CcTest::InitIsolateOnce());
const int kNumParams = 1;
- CodeStubAssemblerTester m(isolate, kNumParams);
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeStubAssembler m(data.state());
m.Return(m.ToString(m.Parameter(kNumParams + 2), m.Parameter(0)));
- Handle<Code> code = m.GenerateCode();
+ Handle<Code> code = data.GenerateCode();
FunctionTester ft(code, kNumParams);
Handle<FixedArray> test_cases = isolate->factory()->NewFixedArray(5);
@@ -179,10 +183,11 @@ TEST(ToString) {
TEST(FlattenString) {
Isolate* isolate(CcTest::InitIsolateOnce());
const int kNumParams = 1;
- CodeStubAssemblerTester m(isolate, kNumParams);
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeStubAssembler m(data.state());
m.Return(m.FlattenString(m.Parameter(0)));
- Handle<Code> code = m.GenerateCode();
+ Handle<Code> code = data.GenerateCode();
FunctionTester ft(code, kNumParams);
Handle<FixedArray> test_cases(isolate->factory()->NewFixedArray(4));
@@ -217,12 +222,13 @@ TEST(FlattenString) {
}
TEST(TryToName) {
- typedef CodeStubAssembler::Label Label;
- typedef CodeStubAssembler::Variable Variable;
+ typedef CodeAssemblerLabel Label;
+ typedef CodeAssemblerVariable Variable;
Isolate* isolate(CcTest::InitIsolateOnce());
const int kNumParams = 3;
- CodeStubAssemblerTester m(isolate, kNumParams);
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeStubAssembler m(data.state());
enum Result { kKeyIsIndex, kKeyIsUnique, kBailout };
{
@@ -261,7 +267,7 @@ TEST(TryToName) {
m.Return(m.BooleanConstant(false));
}
- Handle<Code> code = m.GenerateCode();
+ Handle<Code> code = data.GenerateCode();
FunctionTester ft(code, kNumParams);
Handle<Object> expect_index(Smi::FromInt(kKeyIsIndex), isolate);
@@ -352,14 +358,15 @@ void TestEntryToIndex() {
Isolate* isolate(CcTest::InitIsolateOnce());
const int kNumParams = 1;
- CodeStubAssemblerTester m(isolate, kNumParams);
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeStubAssembler m(data.state());
{
Node* entry = m.SmiUntag(m.Parameter(0));
Node* result = m.EntryToIndex<Dictionary>(entry);
m.Return(m.SmiTag(result));
}
- Handle<Code> code = m.GenerateCode();
+ Handle<Code> code = data.GenerateCode();
FunctionTester ft(code, kNumParams);
// Test a wide range of entries but staying linear in the first 100 entries.
@@ -380,12 +387,13 @@ namespace {
template <typename Dictionary>
void TestNameDictionaryLookup() {
- typedef CodeStubAssembler::Label Label;
- typedef CodeStubAssembler::Variable Variable;
+ typedef CodeAssemblerLabel Label;
+ typedef CodeAssemblerVariable Variable;
Isolate* isolate(CcTest::InitIsolateOnce());
const int kNumParams = 4;
- CodeStubAssemblerTester m(isolate, kNumParams);
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeStubAssembler m(data.state());
enum Result { kFound, kNotFound };
{
@@ -404,7 +412,7 @@ void TestNameDictionaryLookup() {
m.GotoUnless(
m.WordEqual(expected_result, m.SmiConstant(Smi::FromInt(kFound))),
&failed);
- m.Branch(m.Word32Equal(m.SmiToWord32(expected_arg), var_name_index.value()),
+ m.Branch(m.WordEqual(m.SmiUntag(expected_arg), var_name_index.value()),
&passed, &failed);
m.Bind(&if_not_found);
@@ -419,7 +427,7 @@ void TestNameDictionaryLookup() {
m.Return(m.BooleanConstant(false));
}
- Handle<Code> code = m.GenerateCode();
+ Handle<Code> code = data.GenerateCode();
FunctionTester ft(code, kNumParams);
Handle<Object> expect_found(Smi::FromInt(kFound), isolate);
@@ -486,17 +494,18 @@ namespace {
template <typename Dictionary>
void TestNumberDictionaryLookup() {
- typedef CodeStubAssembler::Label Label;
- typedef CodeStubAssembler::Variable Variable;
+ typedef CodeAssemblerLabel Label;
+ typedef CodeAssemblerVariable Variable;
Isolate* isolate(CcTest::InitIsolateOnce());
const int kNumParams = 4;
- CodeStubAssemblerTester m(isolate, kNumParams);
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeStubAssembler m(data.state());
enum Result { kFound, kNotFound };
{
Node* dictionary = m.Parameter(0);
- Node* key = m.SmiToWord32(m.Parameter(1));
+ Node* key = m.SmiUntag(m.Parameter(1));
Node* expected_result = m.Parameter(2);
Node* expected_arg = m.Parameter(3);
@@ -510,8 +519,8 @@ void TestNumberDictionaryLookup() {
m.GotoUnless(
m.WordEqual(expected_result, m.SmiConstant(Smi::FromInt(kFound))),
&failed);
- m.Branch(m.Word32Equal(m.SmiToWord32(expected_arg), var_entry.value()),
- &passed, &failed);
+ m.Branch(m.WordEqual(m.SmiUntag(expected_arg), var_entry.value()), &passed,
+ &failed);
m.Bind(&if_not_found);
m.Branch(
@@ -525,7 +534,7 @@ void TestNumberDictionaryLookup() {
m.Return(m.BooleanConstant(false));
}
- Handle<Code> code = m.GenerateCode();
+ Handle<Code> code = data.GenerateCode();
FunctionTester ft(code, kNumParams);
Handle<Object> expect_found(Smi::FromInt(kFound), isolate);
@@ -624,11 +633,12 @@ void AddProperties(Handle<JSObject> object, Handle<Name> names[],
} // namespace
TEST(TryHasOwnProperty) {
- typedef CodeStubAssembler::Label Label;
+ typedef CodeAssemblerLabel Label;
Isolate* isolate(CcTest::InitIsolateOnce());
const int kNumParams = 4;
- CodeStubAssemblerTester m(isolate, kNumParams);
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeStubAssembler m(data.state());
enum Result { kFound, kNotFound, kBailout };
{
@@ -666,7 +676,7 @@ TEST(TryHasOwnProperty) {
m.Return(m.BooleanConstant(false));
}
- Handle<Code> code = m.GenerateCode();
+ Handle<Code> code = data.GenerateCode();
FunctionTester ft(code, kNumParams);
Handle<Object> expect_found(Smi::FromInt(kFound), isolate);
@@ -808,13 +818,14 @@ TEST(TryHasOwnProperty) {
}
TEST(TryGetOwnProperty) {
- typedef CodeStubAssembler::Label Label;
- typedef CodeStubAssembler::Variable Variable;
+ typedef CodeAssemblerLabel Label;
+ typedef CodeAssemblerVariable Variable;
Isolate* isolate(CcTest::InitIsolateOnce());
Factory* factory = isolate->factory();
const int kNumParams = 2;
- CodeStubAssemblerTester m(isolate, kNumParams);
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeStubAssembler m(data.state());
Handle<Symbol> not_found_symbol = factory->NewSymbol();
Handle<Symbol> bailout_symbol = factory->NewSymbol();
@@ -843,7 +854,7 @@ TEST(TryGetOwnProperty) {
m.Return(m.HeapConstant(bailout_symbol));
}
- Handle<Code> code = m.GenerateCode();
+ Handle<Code> code = data.GenerateCode();
FunctionTester ft(code, kNumParams);
Handle<Name> deleted_property_name =
@@ -1026,16 +1037,17 @@ void AddElement(Handle<JSObject> object, uint32_t index, Handle<Object> value,
} // namespace
TEST(TryLookupElement) {
- typedef CodeStubAssembler::Label Label;
+ typedef CodeAssemblerLabel Label;
Isolate* isolate(CcTest::InitIsolateOnce());
const int kNumParams = 3;
- CodeStubAssemblerTester m(isolate, kNumParams);
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeStubAssembler m(data.state());
enum Result { kFound, kNotFound, kBailout };
{
Node* object = m.Parameter(0);
- Node* index = m.SmiToWord32(m.Parameter(1));
+ Node* index = m.SmiUntag(m.Parameter(1));
Node* expected_result = m.Parameter(2);
Label passed(&m), failed(&m);
@@ -1068,7 +1080,7 @@ TEST(TryLookupElement) {
m.Return(m.BooleanConstant(false));
}
- Handle<Code> code = m.GenerateCode();
+ Handle<Code> code = data.GenerateCode();
FunctionTester ft(code, kNumParams);
Factory* factory = isolate->factory();
@@ -1211,434 +1223,13 @@ TEST(TryLookupElement) {
}
}
-TEST(DeferredCodePhiHints) {
- typedef compiler::Node Node;
- typedef CodeStubAssembler::Label Label;
- typedef CodeStubAssembler::Variable Variable;
- Isolate* isolate(CcTest::InitIsolateOnce());
- VoidDescriptor descriptor(isolate);
- CodeStubAssemblerTester m(isolate, descriptor);
- Label block1(&m, Label::kDeferred);
- m.Goto(&block1);
- m.Bind(&block1);
- {
- Variable var_object(&m, MachineRepresentation::kTagged);
- Label loop(&m, &var_object);
- var_object.Bind(m.IntPtrConstant(0));
- m.Goto(&loop);
- m.Bind(&loop);
- {
- Node* map = m.LoadMap(var_object.value());
- var_object.Bind(map);
- m.Goto(&loop);
- }
- }
- CHECK(!m.GenerateCode().is_null());
-}
-
-TEST(TestOutOfScopeVariable) {
- typedef CodeStubAssembler::Label Label;
- typedef CodeStubAssembler::Variable Variable;
- Isolate* isolate(CcTest::InitIsolateOnce());
- VoidDescriptor descriptor(isolate);
- CodeStubAssemblerTester m(isolate, descriptor);
- Label block1(&m);
- Label block2(&m);
- Label block3(&m);
- Label block4(&m);
- m.Branch(m.WordEqual(m.Parameter(0), m.IntPtrConstant(0)), &block1, &block4);
- m.Bind(&block4);
- {
- Variable var_object(&m, MachineRepresentation::kTagged);
- m.Branch(m.WordEqual(m.Parameter(0), m.IntPtrConstant(0)), &block2,
- &block3);
-
- m.Bind(&block2);
- var_object.Bind(m.IntPtrConstant(55));
- m.Goto(&block1);
-
- m.Bind(&block3);
- var_object.Bind(m.IntPtrConstant(66));
- m.Goto(&block1);
- }
- m.Bind(&block1);
- CHECK(!m.GenerateCode().is_null());
-}
-
-namespace {
-
-void TestStubCacheOffsetCalculation(StubCache::Table table) {
- Isolate* isolate(CcTest::InitIsolateOnce());
- const int kNumParams = 2;
- CodeStubAssemblerTester m(isolate, kNumParams);
-
- {
- Node* name = m.Parameter(0);
- Node* map = m.Parameter(1);
- Node* primary_offset = m.StubCachePrimaryOffset(name, map);
- Node* result;
- if (table == StubCache::kPrimary) {
- result = primary_offset;
- } else {
- CHECK_EQ(StubCache::kSecondary, table);
- result = m.StubCacheSecondaryOffset(name, primary_offset);
- }
- m.Return(m.SmiFromWord32(result));
- }
-
- Handle<Code> code = m.GenerateCode();
- FunctionTester ft(code, kNumParams);
-
- Factory* factory = isolate->factory();
- Handle<Name> names[] = {
- factory->NewSymbol(),
- factory->InternalizeUtf8String("a"),
- factory->InternalizeUtf8String("bb"),
- factory->InternalizeUtf8String("ccc"),
- factory->NewPrivateSymbol(),
- factory->InternalizeUtf8String("dddd"),
- factory->InternalizeUtf8String("eeeee"),
- factory->InternalizeUtf8String("name"),
- factory->NewSymbol(),
- factory->NewPrivateSymbol(),
- };
-
- Handle<Map> maps[] = {
- Handle<Map>(nullptr, isolate),
- factory->cell_map(),
- Map::Create(isolate, 0),
- factory->meta_map(),
- factory->code_map(),
- Map::Create(isolate, 0),
- factory->hash_table_map(),
- factory->symbol_map(),
- factory->string_map(),
- Map::Create(isolate, 0),
- factory->sloppy_arguments_elements_map(),
- };
-
- for (size_t name_index = 0; name_index < arraysize(names); name_index++) {
- Handle<Name> name = names[name_index];
- for (size_t map_index = 0; map_index < arraysize(maps); map_index++) {
- Handle<Map> map = maps[map_index];
-
- int expected_result;
- {
- int primary_offset = StubCache::PrimaryOffsetForTesting(*name, *map);
- if (table == StubCache::kPrimary) {
- expected_result = primary_offset;
- } else {
- expected_result =
- StubCache::SecondaryOffsetForTesting(*name, primary_offset);
- }
- }
- Handle<Object> result = ft.Call(name, map).ToHandleChecked();
-
- Smi* expected = Smi::FromInt(expected_result & Smi::kMaxValue);
- CHECK_EQ(expected, Smi::cast(*result));
- }
- }
-}
-
-} // namespace
-
-TEST(StubCachePrimaryOffset) {
- TestStubCacheOffsetCalculation(StubCache::kPrimary);
-}
-
-TEST(StubCacheSecondaryOffset) {
- TestStubCacheOffsetCalculation(StubCache::kSecondary);
-}
-
-namespace {
-
-Handle<Code> CreateCodeWithFlags(Code::Flags flags) {
- Isolate* isolate(CcTest::InitIsolateOnce());
- CodeStubAssemblerTester m(isolate, flags);
- m.Return(m.UndefinedConstant());
- return m.GenerateCodeCloseAndEscape();
-}
-
-} // namespace
-
-TEST(TryProbeStubCache) {
- typedef CodeStubAssembler::Label Label;
- typedef CodeStubAssembler::Variable Variable;
- Isolate* isolate(CcTest::InitIsolateOnce());
- const int kNumParams = 3;
- CodeStubAssemblerTester m(isolate, kNumParams);
-
- Code::Kind ic_kind = Code::LOAD_IC;
- StubCache stub_cache(isolate, ic_kind);
- stub_cache.Clear();
-
- {
- Node* receiver = m.Parameter(0);
- Node* name = m.Parameter(1);
- Node* expected_handler = m.Parameter(2);
-
- Label passed(&m), failed(&m);
-
- Variable var_handler(&m, MachineRepresentation::kTagged);
- Label if_handler(&m), if_miss(&m);
-
- m.TryProbeStubCache(&stub_cache, receiver, name, &if_handler, &var_handler,
- &if_miss);
- m.Bind(&if_handler);
- m.Branch(m.WordEqual(expected_handler, var_handler.value()), &passed,
- &failed);
-
- m.Bind(&if_miss);
- m.Branch(m.WordEqual(expected_handler, m.IntPtrConstant(0)), &passed,
- &failed);
-
- m.Bind(&passed);
- m.Return(m.BooleanConstant(true));
-
- m.Bind(&failed);
- m.Return(m.BooleanConstant(false));
- }
-
- Handle<Code> code = m.GenerateCode();
- FunctionTester ft(code, kNumParams);
-
- std::vector<Handle<Name>> names;
- std::vector<Handle<JSObject>> receivers;
- std::vector<Handle<Code>> handlers;
-
- base::RandomNumberGenerator rand_gen(FLAG_random_seed);
-
- Factory* factory = isolate->factory();
-
- // Generate some number of names.
- for (int i = 0; i < StubCache::kPrimaryTableSize / 7; i++) {
- Handle<Name> name;
- switch (rand_gen.NextInt(3)) {
- case 0: {
- // Generate string.
- std::stringstream ss;
- ss << "s" << std::hex
- << (rand_gen.NextInt(Smi::kMaxValue) % StubCache::kPrimaryTableSize);
- name = factory->InternalizeUtf8String(ss.str().c_str());
- break;
- }
- case 1: {
- // Generate number string.
- std::stringstream ss;
- ss << (rand_gen.NextInt(Smi::kMaxValue) % StubCache::kPrimaryTableSize);
- name = factory->InternalizeUtf8String(ss.str().c_str());
- break;
- }
- case 2: {
- // Generate symbol.
- name = factory->NewSymbol();
- break;
- }
- default:
- UNREACHABLE();
- }
- names.push_back(name);
- }
-
- // Generate some number of receiver maps and receivers.
- for (int i = 0; i < StubCache::kSecondaryTableSize / 2; i++) {
- Handle<Map> map = Map::Create(isolate, 0);
- receivers.push_back(factory->NewJSObjectFromMap(map));
- }
-
- // Generate some number of handlers.
- for (int i = 0; i < 30; i++) {
- Code::Flags flags =
- Code::RemoveHolderFromFlags(Code::ComputeHandlerFlags(ic_kind));
- handlers.push_back(CreateCodeWithFlags(flags));
- }
-
- // Ensure that GC does happen because from now on we are going to fill our
- // own stub cache instance with raw values.
- DisallowHeapAllocation no_gc;
-
- // Populate {stub_cache}.
- const int N = StubCache::kPrimaryTableSize + StubCache::kSecondaryTableSize;
- for (int i = 0; i < N; i++) {
- int index = rand_gen.NextInt();
- Handle<Name> name = names[index % names.size()];
- Handle<JSObject> receiver = receivers[index % receivers.size()];
- Handle<Code> handler = handlers[index % handlers.size()];
- stub_cache.Set(*name, receiver->map(), *handler);
- }
-
- // Perform some queries.
- bool queried_existing = false;
- bool queried_non_existing = false;
- for (int i = 0; i < N; i++) {
- int index = rand_gen.NextInt();
- Handle<Name> name = names[index % names.size()];
- Handle<JSObject> receiver = receivers[index % receivers.size()];
- Object* handler = stub_cache.Get(*name, receiver->map());
- if (handler == nullptr) {
- queried_non_existing = true;
- } else {
- queried_existing = true;
- }
-
- Handle<Object> expected_handler(handler, isolate);
- ft.CheckTrue(receiver, name, expected_handler);
- }
-
- for (int i = 0; i < N; i++) {
- int index1 = rand_gen.NextInt();
- int index2 = rand_gen.NextInt();
- Handle<Name> name = names[index1 % names.size()];
- Handle<JSObject> receiver = receivers[index2 % receivers.size()];
- Object* handler = stub_cache.Get(*name, receiver->map());
- if (handler == nullptr) {
- queried_non_existing = true;
- } else {
- queried_existing = true;
- }
-
- Handle<Object> expected_handler(handler, isolate);
- ft.CheckTrue(receiver, name, expected_handler);
- }
- // Ensure we performed both kind of queries.
- CHECK(queried_existing && queried_non_existing);
-}
-
-TEST(GotoIfException) {
- typedef CodeStubAssembler::Label Label;
- typedef CodeStubAssembler::Variable Variable;
- Isolate* isolate(CcTest::InitIsolateOnce());
-
- const int kNumParams = 1;
- // Emulate TFJ builtin
- CodeStubAssemblerTester m(isolate, kNumParams, Code::BUILTIN);
-
- Node* context = m.HeapConstant(Handle<Context>(isolate->native_context()));
- Node* to_string_tag =
- m.HeapConstant(isolate->factory()->to_string_tag_symbol());
- Variable exception(&m, MachineRepresentation::kTagged);
-
- Label exception_handler(&m);
- Callable to_string = CodeFactory::ToString(isolate);
- Node* string = m.CallStub(to_string, context, to_string_tag);
- m.GotoIfException(string, &exception_handler, &exception);
- m.Return(string);
-
- m.Bind(&exception_handler);
- m.Return(exception.value());
-
- Handle<Code> code = m.GenerateCode();
- CHECK(!code.is_null());
-
- FunctionTester ft(code, kNumParams);
- Handle<Object> result = ft.Call().ToHandleChecked();
-
- // Should be a TypeError
- CHECK(result->IsJSObject());
-
- Handle<Object> constructor =
- Object::GetPropertyOrElement(result,
- isolate->factory()->constructor_string())
- .ToHandleChecked();
- CHECK(constructor->SameValue(*isolate->type_error_function()));
-}
-
-TEST(GotoIfExceptionMultiple) {
- typedef CodeStubAssembler::Label Label;
- typedef CodeStubAssembler::Variable Variable;
- Isolate* isolate(CcTest::InitIsolateOnce());
-
- const int kNumParams = 4; // receiver, first, second, third
- // Emulate TFJ builtin
- CodeStubAssemblerTester m(isolate, kNumParams, Code::BUILTIN);
-
- Node* context = m.HeapConstant(Handle<Context>(isolate->native_context()));
- Node* first_value = m.Parameter(0);
- Node* second_value = m.Parameter(1);
- Node* third_value = m.Parameter(2);
-
- Label exception_handler1(&m);
- Label exception_handler2(&m);
- Label exception_handler3(&m);
- Variable return_value(&m, MachineRepresentation::kWord32);
- Variable error(&m, MachineRepresentation::kTagged);
-
- return_value.Bind(m.Int32Constant(0));
-
- // try { return ToString(param1) } catch (e) { ... }
- Callable to_string = CodeFactory::ToString(isolate);
- Node* string = m.CallStub(to_string, context, first_value);
- m.GotoIfException(string, &exception_handler1, &error);
- m.Return(string);
-
- // try { ToString(param2); return 7 } catch (e) { ... }
- m.Bind(&exception_handler1);
- return_value.Bind(m.Int32Constant(7));
- error.Bind(m.UndefinedConstant());
- string = m.CallStub(to_string, context, second_value);
- m.GotoIfException(string, &exception_handler2, &error);
- m.Return(m.SmiFromWord32(return_value.value()));
-
- // try { ToString(param3); return 7 & ~2; } catch (e) { return e; }
- m.Bind(&exception_handler2);
- // Return returnValue & ~2
- error.Bind(m.UndefinedConstant());
- string = m.CallStub(to_string, context, third_value);
- m.GotoIfException(string, &exception_handler3, &error);
- m.Return(m.SmiFromWord32(
- m.Word32And(return_value.value(),
- m.Word32Xor(m.Int32Constant(2), m.Int32Constant(-1)))));
-
- m.Bind(&exception_handler3);
- m.Return(error.value());
-
- Handle<Code> code = m.GenerateCode();
- CHECK(!code.is_null());
-
- FunctionTester ft(code, kNumParams);
-
- Handle<Object> result;
- // First handler does not throw, returns result of first value
- result = ft.Call(isolate->factory()->undefined_value(),
- isolate->factory()->to_string_tag_symbol())
- .ToHandleChecked();
- CHECK(String::cast(*result)->IsOneByteEqualTo(OneByteVector("undefined")));
-
- // First handler returns a number
- result = ft.Call(isolate->factory()->to_string_tag_symbol(),
- isolate->factory()->undefined_value())
- .ToHandleChecked();
- CHECK_EQ(7, Smi::cast(*result)->value());
-
- // First handler throws, second handler returns a number
- result = ft.Call(isolate->factory()->to_string_tag_symbol(),
- isolate->factory()->to_primitive_symbol())
- .ToHandleChecked();
- CHECK_EQ(7 & ~2, Smi::cast(*result)->value());
-
- // First handler throws, second handler throws, third handler returns thrown
- // value.
- result = ft.Call(isolate->factory()->to_string_tag_symbol(),
- isolate->factory()->to_primitive_symbol(),
- isolate->factory()->unscopables_symbol())
- .ToHandleChecked();
-
- // Should be a TypeError
- CHECK(result->IsJSObject());
-
- Handle<Object> constructor =
- Object::GetPropertyOrElement(result,
- isolate->factory()->constructor_string())
- .ToHandleChecked();
- CHECK(constructor->SameValue(*isolate->type_error_function()));
-}
-
TEST(AllocateJSObjectFromMap) {
Isolate* isolate(CcTest::InitIsolateOnce());
Factory* factory = isolate->factory();
const int kNumParams = 3;
- CodeStubAssemblerTester m(isolate, kNumParams);
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeStubAssembler m(data.state());
{
Node* map = m.Parameter(0);
@@ -1650,7 +1241,7 @@ TEST(AllocateJSObjectFromMap) {
m.Return(result);
}
- Handle<Code> code = m.GenerateCode();
+ Handle<Code> code = data.GenerateCode();
FunctionTester ft(code, kNumParams);
Handle<Map> maps[] = {
@@ -1701,7 +1292,8 @@ TEST(AllocateNameDictionary) {
Isolate* isolate(CcTest::InitIsolateOnce());
const int kNumParams = 1;
- CodeStubAssemblerTester m(isolate, kNumParams);
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeStubAssembler m(data.state());
{
Node* capacity = m.Parameter(0);
@@ -1709,7 +1301,7 @@ TEST(AllocateNameDictionary) {
m.Return(result);
}
- Handle<Code> code = m.GenerateCode();
+ Handle<Code> code = data.GenerateCode();
FunctionTester ft(code, kNumParams);
{
@@ -1729,16 +1321,17 @@ TEST(PopAndReturnConstant) {
Isolate* isolate(CcTest::InitIsolateOnce());
const int kNumParams = 4;
- const int kNumProgramaticParams = 2;
- CodeStubAssemblerTester m(isolate, kNumParams - kNumProgramaticParams);
+ const int kNumProgrammaticParams = 2;
+ CodeAssemblerTester data(isolate, kNumParams - kNumProgrammaticParams);
+ CodeStubAssembler m(data.state());
// Call a function that return |kNumProgramaticParams| parameters in addition
// to those specified by the static descriptor. |kNumProgramaticParams| is
// specified as a constant.
- m.PopAndReturn(m.Int32Constant(kNumProgramaticParams),
+ m.PopAndReturn(m.Int32Constant(kNumProgrammaticParams),
m.SmiConstant(Smi::FromInt(1234)));
- Handle<Code> code = m.GenerateCode();
+ Handle<Code> code = data.GenerateCode();
CHECK(!code.is_null());
FunctionTester ft(code, kNumParams);
@@ -1757,8 +1350,9 @@ TEST(PopAndReturnVariable) {
Isolate* isolate(CcTest::InitIsolateOnce());
const int kNumParams = 4;
- const int kNumProgramaticParams = 2;
- CodeStubAssemblerTester m(isolate, kNumParams - kNumProgramaticParams);
+ const int kNumProgrammaticParams = 2;
+ CodeAssemblerTester data(isolate, kNumParams - kNumProgrammaticParams);
+ CodeStubAssembler m(data.state());
// Call a function that return |kNumProgramaticParams| parameters in addition
// to those specified by the static descriptor. |kNumProgramaticParams| is
@@ -1766,7 +1360,7 @@ TEST(PopAndReturnVariable) {
// a constant.
m.PopAndReturn(m.SmiUntag(m.Parameter(1)), m.SmiConstant(Smi::FromInt(1234)));
- Handle<Code> code = m.GenerateCode();
+ Handle<Code> code = data.GenerateCode();
CHECK(!code.is_null());
FunctionTester ft(code, kNumParams);
@@ -1775,7 +1369,7 @@ TEST(PopAndReturnVariable) {
result = ft.Call(isolate->factory()->undefined_value(),
Handle<Smi>(Smi::FromInt(1234), isolate),
isolate->factory()->undefined_value(),
- Handle<Smi>(Smi::FromInt(kNumProgramaticParams), isolate))
+ Handle<Smi>(Smi::FromInt(kNumProgrammaticParams), isolate))
.ToHandleChecked();
CHECK_EQ(1234, Handle<Smi>::cast(result)->value());
}
@@ -1784,7 +1378,9 @@ TEST(PopAndReturnVariable) {
TEST(OneToTwoByteStringCopy) {
Isolate* isolate(CcTest::InitIsolateOnce());
- CodeStubAssemblerTester m(isolate, 2);
+ const int kNumParams = 2;
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeStubAssembler m(data.state());
m.CopyStringCharacters(
m.Parameter(0), m.Parameter(1), m.SmiConstant(Smi::FromInt(0)),
@@ -1793,7 +1389,7 @@ TEST(OneToTwoByteStringCopy) {
CodeStubAssembler::SMI_PARAMETERS);
m.Return(m.SmiConstant(Smi::FromInt(0)));
- Handle<Code> code = m.GenerateCode();
+ Handle<Code> code = data.GenerateCode();
CHECK(!code.is_null());
Handle<String> string1 = isolate->factory()->InternalizeUtf8String("abcde");
@@ -1818,7 +1414,9 @@ TEST(OneToTwoByteStringCopy) {
TEST(OneToOneByteStringCopy) {
Isolate* isolate(CcTest::InitIsolateOnce());
- CodeStubAssemblerTester m(isolate, 2);
+ const int kNumParams = 2;
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeStubAssembler m(data.state());
m.CopyStringCharacters(
m.Parameter(0), m.Parameter(1), m.SmiConstant(Smi::FromInt(0)),
@@ -1827,7 +1425,7 @@ TEST(OneToOneByteStringCopy) {
CodeStubAssembler::SMI_PARAMETERS);
m.Return(m.SmiConstant(Smi::FromInt(0)));
- Handle<Code> code = m.GenerateCode();
+ Handle<Code> code = data.GenerateCode();
CHECK(!code.is_null());
Handle<String> string1 = isolate->factory()->InternalizeUtf8String("abcde");
@@ -1852,7 +1450,9 @@ TEST(OneToOneByteStringCopy) {
TEST(OneToOneByteStringCopyNonZeroStart) {
Isolate* isolate(CcTest::InitIsolateOnce());
- CodeStubAssemblerTester m(isolate, 2);
+ const int kNumParams = 2;
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeStubAssembler m(data.state());
m.CopyStringCharacters(
m.Parameter(0), m.Parameter(1), m.SmiConstant(Smi::FromInt(0)),
@@ -1861,7 +1461,7 @@ TEST(OneToOneByteStringCopyNonZeroStart) {
CodeStubAssembler::SMI_PARAMETERS);
m.Return(m.SmiConstant(Smi::FromInt(0)));
- Handle<Code> code = m.GenerateCode();
+ Handle<Code> code = data.GenerateCode();
CHECK(!code.is_null());
Handle<String> string1 = isolate->factory()->InternalizeUtf8String("abcde");
@@ -1883,7 +1483,9 @@ TEST(OneToOneByteStringCopyNonZeroStart) {
TEST(TwoToTwoByteStringCopy) {
Isolate* isolate(CcTest::InitIsolateOnce());
- CodeStubAssemblerTester m(isolate, 2);
+ const int kNumParams = 2;
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeStubAssembler m(data.state());
m.CopyStringCharacters(
m.Parameter(0), m.Parameter(1), m.SmiConstant(Smi::FromInt(0)),
@@ -1892,7 +1494,7 @@ TEST(TwoToTwoByteStringCopy) {
CodeStubAssembler::SMI_PARAMETERS);
m.Return(m.SmiConstant(Smi::FromInt(0)));
- Handle<Code> code = m.GenerateCode();
+ Handle<Code> code = data.GenerateCode();
CHECK(!code.is_null());
uc16 array1[] = {2000, 2001, 2002, 2003, 2004};
@@ -1921,9 +1523,10 @@ TEST(Arguments) {
Isolate* isolate(CcTest::InitIsolateOnce());
const int kNumParams = 4;
- CodeStubAssemblerTester m(isolate, kNumParams);
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeStubAssembler m(data.state());
- CodeStubArguments arguments(&m, m.IntPtrConstant(3));
+ CodeStubArguments arguments(&m, m.Int32Constant(3));
CSA_ASSERT(
&m, m.WordEqual(arguments.AtIndex(0), m.SmiConstant(Smi::FromInt(12))));
@@ -1934,7 +1537,7 @@ TEST(Arguments) {
m.Return(arguments.GetReceiver());
- Handle<Code> code = m.GenerateCode();
+ Handle<Code> code = data.GenerateCode();
CHECK(!code.is_null());
FunctionTester ft(code, kNumParams);
@@ -1950,23 +1553,22 @@ TEST(ArgumentsForEach) {
Isolate* isolate(CcTest::InitIsolateOnce());
const int kNumParams = 4;
- CodeStubAssemblerTester m(isolate, kNumParams);
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeStubAssembler m(data.state());
- CodeStubArguments arguments(&m, m.IntPtrConstant(3));
+ CodeStubArguments arguments(&m, m.Int32Constant(3));
- CodeStubAssemblerTester::Variable sum(&m,
- MachineType::PointerRepresentation());
- CodeStubAssemblerTester::VariableList list({&sum}, m.zone());
+ CodeAssemblerVariable sum(&m, MachineRepresentation::kTagged);
+ CodeAssemblerVariableList list({&sum}, m.zone());
- sum.Bind(m.IntPtrConstant(0));
+ sum.Bind(m.SmiConstant(0));
- arguments.ForEach(list, [&m, &sum](CodeStubAssembler* assembler, Node* arg) {
- sum.Bind(assembler->IntPtrAdd(sum.value(), arg));
- });
+ arguments.ForEach(
+ list, [&m, &sum](Node* arg) { sum.Bind(m.SmiAdd(sum.value(), arg)); });
m.Return(sum.value());
- Handle<Code> code = m.GenerateCode();
+ Handle<Code> code = data.GenerateCode();
CHECK(!code.is_null());
FunctionTester ft(code, kNumParams);
@@ -1978,5 +1580,907 @@ TEST(ArgumentsForEach) {
CHECK_EQ(Smi::FromInt(12 + 13 + 14), *result);
}
+TEST(IsDebugActive) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+
+ const int kNumParams = 1;
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeStubAssembler m(data.state());
+
+ CodeAssemblerLabel if_active(&m), if_not_active(&m);
+
+ m.Branch(m.IsDebugActive(), &if_active, &if_not_active);
+ m.Bind(&if_active);
+ m.Return(m.TrueConstant());
+ m.Bind(&if_not_active);
+ m.Return(m.FalseConstant());
+
+ Handle<Code> code = data.GenerateCode();
+ CHECK(!code.is_null());
+
+ FunctionTester ft(code, kNumParams);
+ CHECK_EQ(false, isolate->debug()->is_active());
+ Handle<Object> result =
+ ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
+ CHECK_EQ(isolate->heap()->false_value(), *result);
+
+ bool* debug_is_active = reinterpret_cast<bool*>(
+ ExternalReference::debug_is_active_address(isolate).address());
+
+ // Cheat to enable debug (TODO: do this properly).
+ *debug_is_active = true;
+
+ result = ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
+ CHECK_EQ(isolate->heap()->true_value(), *result);
+
+ // Reset debug mode.
+ *debug_is_active = false;
+}
+
+class AppendJSArrayCodeStubAssembler : public CodeStubAssembler {
+ public:
+ AppendJSArrayCodeStubAssembler(compiler::CodeAssemblerState* state,
+ ElementsKind kind)
+ : CodeStubAssembler(state), kind_(kind) {}
+
+ void TestAppendJSArrayImpl(Isolate* isolate, CodeAssemblerTester* tester,
+ Object* o1, Object* o2, Object* o3, Object* o4,
+ int initial_size, int result_size) {
+ typedef CodeAssemblerVariable Variable;
+ typedef CodeAssemblerLabel Label;
+ Handle<JSArray> array = isolate->factory()->NewJSArray(
+ kind_, 2, initial_size, INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
+ JSObject::SetElement(isolate, array, 0,
+ Handle<Smi>(Smi::FromInt(1), isolate), SLOPPY)
+ .Check();
+ JSObject::SetElement(isolate, array, 1,
+ Handle<Smi>(Smi::FromInt(2), isolate), SLOPPY)
+ .Check();
+ CodeStubArguments args(this, Int32Constant(kNumParams));
+ Variable arg_index(this, MachineType::PointerRepresentation());
+ Label bailout(this);
+ arg_index.Bind(IntPtrConstant(0));
+ Node* length = BuildAppendJSArray(
+ kind_, HeapConstant(Handle<HeapObject>(isolate->context(), isolate)),
+ HeapConstant(array), args, arg_index, &bailout);
+ Return(length);
+
+ Bind(&bailout);
+ Return(SmiTag(IntPtrAdd(arg_index.value(), IntPtrConstant(2))));
+
+ Handle<Code> code = tester->GenerateCode();
+ CHECK(!code.is_null());
+
+ FunctionTester ft(code, kNumParams);
+
+ Handle<Object> result =
+ ft.Call(Handle<Object>(o1, isolate), Handle<Object>(o2, isolate),
+ Handle<Object>(o3, isolate), Handle<Object>(o4, isolate))
+ .ToHandleChecked();
+
+ CHECK_EQ(kind_, array->GetElementsKind());
+ CHECK_EQ(result_size, Handle<Smi>::cast(result)->value());
+ CHECK_EQ(result_size, Smi::cast(array->length())->value());
+ Object* obj = *JSObject::GetElement(isolate, array, 2).ToHandleChecked();
+ CHECK_EQ(result_size < 3 ? isolate->heap()->undefined_value() : o1, obj);
+ obj = *JSObject::GetElement(isolate, array, 3).ToHandleChecked();
+ CHECK_EQ(result_size < 4 ? isolate->heap()->undefined_value() : o2, obj);
+ obj = *JSObject::GetElement(isolate, array, 4).ToHandleChecked();
+ CHECK_EQ(result_size < 5 ? isolate->heap()->undefined_value() : o3, obj);
+ obj = *JSObject::GetElement(isolate, array, 5).ToHandleChecked();
+ CHECK_EQ(result_size < 6 ? isolate->heap()->undefined_value() : o4, obj);
+ }
+
+ static void TestAppendJSArray(Isolate* isolate, ElementsKind kind, Object* o1,
+ Object* o2, Object* o3, Object* o4,
+ int initial_size, int result_size) {
+ CodeAssemblerTester data(isolate, kNumParams);
+ AppendJSArrayCodeStubAssembler m(data.state(), kind);
+ m.TestAppendJSArrayImpl(isolate, &data, o1, o2, o3, o4, initial_size,
+ result_size);
+ }
+
+ private:
+ static const int kNumParams = 4;
+ ElementsKind kind_;
+};
+
+TEST(BuildAppendJSArrayFastElement) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+ AppendJSArrayCodeStubAssembler::TestAppendJSArray(
+ isolate, FAST_ELEMENTS, Smi::FromInt(3), Smi::FromInt(4), Smi::FromInt(5),
+ Smi::FromInt(6), 6, 6);
+}
+
+TEST(BuildAppendJSArrayFastElementGrow) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+ AppendJSArrayCodeStubAssembler::TestAppendJSArray(
+ isolate, FAST_ELEMENTS, Smi::FromInt(3), Smi::FromInt(4), Smi::FromInt(5),
+ Smi::FromInt(6), 2, 6);
+}
+
+TEST(BuildAppendJSArrayFastSmiElement) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+ AppendJSArrayCodeStubAssembler::TestAppendJSArray(
+ isolate, FAST_SMI_ELEMENTS, Smi::FromInt(3), Smi::FromInt(4),
+ Smi::FromInt(5), Smi::FromInt(6), 6, 6);
+}
+
+TEST(BuildAppendJSArrayFastSmiElementGrow) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+ AppendJSArrayCodeStubAssembler::TestAppendJSArray(
+ isolate, FAST_SMI_ELEMENTS, Smi::FromInt(3), Smi::FromInt(4),
+ Smi::FromInt(5), Smi::FromInt(6), 2, 6);
+}
+
+TEST(BuildAppendJSArrayFastSmiElementObject) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+ AppendJSArrayCodeStubAssembler::TestAppendJSArray(
+ isolate, FAST_SMI_ELEMENTS, Smi::FromInt(3), Smi::FromInt(4),
+ isolate->heap()->undefined_value(), Smi::FromInt(6), 6, 4);
+}
+
+TEST(BuildAppendJSArrayFastSmiElementObjectGrow) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+ AppendJSArrayCodeStubAssembler::TestAppendJSArray(
+ isolate, FAST_SMI_ELEMENTS, Smi::FromInt(3), Smi::FromInt(4),
+ isolate->heap()->undefined_value(), Smi::FromInt(6), 2, 4);
+}
+
+TEST(BuildAppendJSArrayFastDoubleElements) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+ AppendJSArrayCodeStubAssembler::TestAppendJSArray(
+ isolate, FAST_DOUBLE_ELEMENTS, Smi::FromInt(3), Smi::FromInt(4),
+ Smi::FromInt(5), Smi::FromInt(6), 6, 6);
+}
+
+TEST(BuildAppendJSArrayFastDoubleElementsGrow) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+ AppendJSArrayCodeStubAssembler::TestAppendJSArray(
+ isolate, FAST_DOUBLE_ELEMENTS, Smi::FromInt(3), Smi::FromInt(4),
+ Smi::FromInt(5), Smi::FromInt(6), 2, 6);
+}
+
+TEST(BuildAppendJSArrayFastDoubleElementsObject) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+ AppendJSArrayCodeStubAssembler::TestAppendJSArray(
+ isolate, FAST_DOUBLE_ELEMENTS, Smi::FromInt(3), Smi::FromInt(4),
+ isolate->heap()->undefined_value(), Smi::FromInt(6), 6, 4);
+}
+
+namespace {
+
+template <typename Stub, typename... Args>
+void Recompile(Args... args) {
+ Stub stub(args...);
+ stub.DeleteStubFromCacheForTesting();
+ stub.GetCode();
+}
+
+} // namespace
+
+void CustomPromiseHook(v8::PromiseHookType type, v8::Local<v8::Promise> promise,
+ v8::Local<v8::Value> parentPromise) {}
+
+TEST(IsPromiseHookEnabled) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+
+ const int kNumParams = 1;
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeStubAssembler m(data.state());
+
+ m.Return(m.SelectBooleanConstant(m.IsPromiseHookEnabled()));
+
+ Handle<Code> code = data.GenerateCode();
+ CHECK(!code.is_null());
+
+ FunctionTester ft(code, kNumParams);
+ Handle<Object> result =
+ ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
+ CHECK_EQ(isolate->heap()->false_value(), *result);
+
+ isolate->SetPromiseHook(CustomPromiseHook);
+ result = ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
+ CHECK_EQ(isolate->heap()->true_value(), *result);
+
+ isolate->SetPromiseHook(nullptr);
+ result = ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
+ CHECK_EQ(isolate->heap()->false_value(), *result);
+}
+
+TEST(AllocateAndInitJSPromise) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+
+ const int kNumParams = 1;
+ CodeAssemblerTester data(isolate, kNumParams);
+ PromiseBuiltinsAssembler m(data.state());
+
+ Node* const context = m.Parameter(kNumParams + 2);
+ Node* const promise = m.AllocateAndInitJSPromise(context);
+ m.Return(promise);
+
+ Handle<Code> code = data.GenerateCode();
+ CHECK(!code.is_null());
+
+ FunctionTester ft(code, kNumParams);
+ Handle<Object> result =
+ ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
+ CHECK(result->IsJSPromise());
+}
+
+TEST(AllocateAndSetJSPromise) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+
+ const int kNumParams = 1;
+ CodeAssemblerTester data(isolate, kNumParams);
+ PromiseBuiltinsAssembler m(data.state());
+
+ Node* const context = m.Parameter(kNumParams + 2);
+ Node* const promise = m.AllocateAndSetJSPromise(
+ context, m.SmiConstant(v8::Promise::kPending), m.SmiConstant(1));
+ m.Return(promise);
+
+ Handle<Code> code = data.GenerateCode();
+ CHECK(!code.is_null());
+
+ FunctionTester ft(code, kNumParams);
+ Handle<Object> result =
+ ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
+ CHECK(result->IsJSPromise());
+ Handle<JSPromise> js_promise = Handle<JSPromise>::cast(result);
+ CHECK_EQ(v8::Promise::kPending, js_promise->status());
+ CHECK_EQ(Smi::FromInt(1), js_promise->result());
+ CHECK(!js_promise->has_handler());
+}
+
+TEST(AllocatePromiseReactionJobInfo) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+
+ const int kNumParams = 1;
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeStubAssembler m(data.state());
+ PromiseBuiltinsAssembler p(data.state());
+
+ Node* const context = m.Parameter(kNumParams + 2);
+ Node* const tasks = m.AllocateFixedArray(FAST_ELEMENTS, m.IntPtrConstant(1));
+ m.StoreFixedArrayElement(tasks, 0, m.UndefinedConstant());
+ Node* const deferred_promise =
+ m.AllocateFixedArray(FAST_ELEMENTS, m.IntPtrConstant(1));
+ m.StoreFixedArrayElement(deferred_promise, 0, m.UndefinedConstant());
+ Node* const info = m.AllocatePromiseReactionJobInfo(
+ m.SmiConstant(1), tasks, deferred_promise, m.UndefinedConstant(),
+ m.UndefinedConstant(), context);
+ m.Return(info);
+
+ Handle<Code> code = data.GenerateCode();
+ CHECK(!code.is_null());
+
+ FunctionTester ft(code, kNumParams);
+ Handle<Object> result =
+ ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
+ CHECK(result->IsPromiseReactionJobInfo());
+ Handle<PromiseReactionJobInfo> promise_info =
+ Handle<PromiseReactionJobInfo>::cast(result);
+ CHECK_EQ(Smi::FromInt(1), promise_info->value());
+ CHECK(promise_info->tasks()->IsFixedArray());
+ CHECK(promise_info->deferred_promise()->IsFixedArray());
+ CHECK(promise_info->deferred_on_resolve()->IsUndefined(isolate));
+ CHECK(promise_info->deferred_on_reject()->IsUndefined(isolate));
+ CHECK(promise_info->context()->IsContext());
+ CHECK_EQ(kDebugPromiseNoID, promise_info->debug_id());
+}
+
+TEST(AllocatePromiseResolveThenableJobInfo) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+
+ const int kNumParams = 1;
+ CodeAssemblerTester data(isolate, kNumParams);
+ PromiseBuiltinsAssembler p(data.state());
+
+ Node* const context = p.Parameter(kNumParams + 2);
+ Node* const native_context = p.LoadNativeContext(context);
+ Node* const thenable = p.AllocateAndInitJSPromise(context);
+ Node* const then_str = p.HeapConstant(isolate->factory()->then_string());
+ Callable getproperty_callable = CodeFactory::GetProperty(isolate);
+ Node* const then =
+ p.CallStub(getproperty_callable, context, thenable, then_str);
+ Node* resolve = nullptr;
+ Node* reject = nullptr;
+ std::tie(resolve, reject) = p.CreatePromiseResolvingFunctions(
+ thenable, p.FalseConstant(), native_context);
+
+ Node* const info = p.AllocatePromiseResolveThenableJobInfo(
+ thenable, then, resolve, reject, context);
+ p.Return(info);
+
+ Handle<Code> code = data.GenerateCode();
+ CHECK(!code.is_null());
+
+ FunctionTester ft(code, kNumParams);
+ Handle<Object> result =
+ ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
+ CHECK(result->IsPromiseResolveThenableJobInfo());
+ Handle<PromiseResolveThenableJobInfo> promise_info =
+ Handle<PromiseResolveThenableJobInfo>::cast(result);
+ CHECK(promise_info->thenable()->IsJSPromise());
+ CHECK(promise_info->then()->IsJSFunction());
+ CHECK(promise_info->resolve()->IsJSFunction());
+ CHECK(promise_info->reject()->IsJSFunction());
+ CHECK_EQ(kDebugPromiseNoID, promise_info->debug_id());
+ CHECK(promise_info->context()->IsContext());
+}
+
+TEST(IsSymbol) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+
+ const int kNumParams = 1;
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeStubAssembler m(data.state());
+
+ Node* const symbol = m.Parameter(0);
+ m.Return(m.SelectBooleanConstant(m.IsSymbol(symbol)));
+
+ Handle<Code> code = data.GenerateCode();
+ CHECK(!code.is_null());
+
+ FunctionTester ft(code, kNumParams);
+ Handle<Object> result =
+ ft.Call(isolate->factory()->NewSymbol()).ToHandleChecked();
+ CHECK_EQ(isolate->heap()->true_value(), *result);
+
+ result = ft.Call(isolate->factory()->empty_string()).ToHandleChecked();
+ CHECK_EQ(isolate->heap()->false_value(), *result);
+}
+
+TEST(IsPrivateSymbol) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+
+ const int kNumParams = 1;
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeStubAssembler m(data.state());
+
+ Node* const symbol = m.Parameter(0);
+ m.Return(m.SelectBooleanConstant(m.IsPrivateSymbol(symbol)));
+
+ Handle<Code> code = data.GenerateCode();
+ CHECK(!code.is_null());
+
+ FunctionTester ft(code, kNumParams);
+ Handle<Object> result =
+ ft.Call(isolate->factory()->NewSymbol()).ToHandleChecked();
+ CHECK_EQ(isolate->heap()->false_value(), *result);
+
+ result = ft.Call(isolate->factory()->empty_string()).ToHandleChecked();
+ CHECK_EQ(isolate->heap()->false_value(), *result);
+
+ result = ft.Call(isolate->factory()->NewPrivateSymbol()).ToHandleChecked();
+ CHECK_EQ(isolate->heap()->true_value(), *result);
+}
+
+TEST(PromiseHasHandler) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+
+ const int kNumParams = 1;
+ CodeAssemblerTester data(isolate, kNumParams);
+ PromiseBuiltinsAssembler m(data.state());
+
+ Node* const context = m.Parameter(kNumParams + 2);
+ Node* const promise =
+ m.AllocateAndInitJSPromise(context, m.UndefinedConstant());
+ m.Return(m.SelectBooleanConstant(m.PromiseHasHandler(promise)));
+
+ Handle<Code> code = data.GenerateCode();
+ CHECK(!code.is_null());
+
+ FunctionTester ft(code, kNumParams);
+ Handle<Object> result =
+ ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
+ CHECK_EQ(isolate->heap()->false_value(), *result);
+}
+
+TEST(CreatePromiseResolvingFunctionsContext) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+
+ const int kNumParams = 1;
+ CodeAssemblerTester data(isolate, kNumParams);
+ PromiseBuiltinsAssembler m(data.state());
+
+ Node* const context = m.Parameter(kNumParams + 2);
+ Node* const native_context = m.LoadNativeContext(context);
+ Node* const promise =
+ m.AllocateAndInitJSPromise(context, m.UndefinedConstant());
+ Node* const promise_context = m.CreatePromiseResolvingFunctionsContext(
+ promise, m.BooleanConstant(false), native_context);
+ m.Return(promise_context);
+
+ Handle<Code> code = data.GenerateCode();
+ CHECK(!code.is_null());
+
+ FunctionTester ft(code, kNumParams);
+ Handle<Object> result =
+ ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
+ CHECK(result->IsContext());
+ Handle<Context> context_js = Handle<Context>::cast(result);
+ CHECK_EQ(isolate->native_context()->closure(), context_js->closure());
+ CHECK_EQ(isolate->heap()->the_hole_value(), context_js->extension());
+ CHECK_EQ(*isolate->native_context(), context_js->native_context());
+ CHECK_EQ(Smi::FromInt(0),
+ context_js->get(PromiseBuiltinsAssembler::kAlreadyVisitedSlot));
+ CHECK(context_js->get(PromiseBuiltinsAssembler::kPromiseSlot)->IsJSPromise());
+ CHECK_EQ(isolate->heap()->false_value(),
+ context_js->get(PromiseBuiltinsAssembler::kDebugEventSlot));
+}
+
+TEST(CreatePromiseResolvingFunctions) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+
+ const int kNumParams = 1;
+ CodeAssemblerTester data(isolate, kNumParams);
+ PromiseBuiltinsAssembler m(data.state());
+
+ Node* const context = m.Parameter(kNumParams + 2);
+ Node* const native_context = m.LoadNativeContext(context);
+ Node* const promise =
+ m.AllocateAndInitJSPromise(context, m.UndefinedConstant());
+ Node *resolve, *reject;
+ std::tie(resolve, reject) = m.CreatePromiseResolvingFunctions(
+ promise, m.BooleanConstant(false), native_context);
+ Node* const kSize = m.IntPtrConstant(2);
+ Node* const arr = m.AllocateFixedArray(FAST_ELEMENTS, kSize);
+ m.StoreFixedArrayElement(arr, 0, resolve);
+ m.StoreFixedArrayElement(arr, 1, reject);
+ m.Return(arr);
+
+ Handle<Code> code = data.GenerateCode();
+ CHECK(!code.is_null());
+
+ FunctionTester ft(code, kNumParams);
+ Handle<Object> result_obj =
+ ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
+ CHECK(result_obj->IsFixedArray());
+ Handle<FixedArray> result_arr = Handle<FixedArray>::cast(result_obj);
+ CHECK(result_arr->get(0)->IsJSFunction());
+ CHECK(result_arr->get(1)->IsJSFunction());
+}
+
+TEST(NewElementsCapacity) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+ CodeAssemblerTester data(isolate, 1);
+ CodeStubAssembler m(data.state());
+ m.Return(m.SmiTag(m.CalculateNewElementsCapacity(
+ m.SmiUntag(m.Parameter(0)), CodeStubAssembler::INTPTR_PARAMETERS)));
+ Handle<Code> code = data.GenerateCode();
+ CHECK(!code.is_null());
+ FunctionTester ft(code, 1);
+ Handle<Smi> test_value = Handle<Smi>(Smi::FromInt(0), isolate);
+ Handle<Smi> result_obj =
+ Handle<Smi>::cast(ft.Call(test_value).ToHandleChecked());
+ CHECK_EQ(
+ result_obj->value(),
+ static_cast<int>(JSObject::NewElementsCapacity(test_value->value())));
+ test_value = Handle<Smi>(Smi::FromInt(1), isolate);
+ result_obj = Handle<Smi>::cast(ft.Call(test_value).ToHandleChecked());
+ CHECK_EQ(
+ result_obj->value(),
+ static_cast<int>(JSObject::NewElementsCapacity(test_value->value())));
+ test_value = Handle<Smi>(Smi::FromInt(2), isolate);
+ result_obj = Handle<Smi>::cast(ft.Call(test_value).ToHandleChecked());
+ CHECK_EQ(
+ result_obj->value(),
+ static_cast<int>(JSObject::NewElementsCapacity(test_value->value())));
+ test_value = Handle<Smi>(Smi::FromInt(1025), isolate);
+ result_obj = Handle<Smi>::cast(ft.Call(test_value).ToHandleChecked());
+ CHECK_EQ(
+ result_obj->value(),
+ static_cast<int>(JSObject::NewElementsCapacity(test_value->value())));
+}
+
+TEST(NewElementsCapacitySmi) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+ CodeAssemblerTester data(isolate, 1);
+ CodeStubAssembler m(data.state());
+ m.Return(m.CalculateNewElementsCapacity(m.Parameter(0),
+ CodeStubAssembler::SMI_PARAMETERS));
+ Handle<Code> code = data.GenerateCode();
+ CHECK(!code.is_null());
+ FunctionTester ft(code, 1);
+ Handle<Smi> test_value = Handle<Smi>(Smi::FromInt(0), isolate);
+ Handle<Smi> result_obj =
+ Handle<Smi>::cast(ft.Call(test_value).ToHandleChecked());
+ CHECK_EQ(
+ result_obj->value(),
+ static_cast<int>(JSObject::NewElementsCapacity(test_value->value())));
+ test_value = Handle<Smi>(Smi::FromInt(1), isolate);
+ result_obj = Handle<Smi>::cast(ft.Call(test_value).ToHandleChecked());
+ CHECK_EQ(
+ result_obj->value(),
+ static_cast<int>(JSObject::NewElementsCapacity(test_value->value())));
+ test_value = Handle<Smi>(Smi::FromInt(2), isolate);
+ result_obj = Handle<Smi>::cast(ft.Call(test_value).ToHandleChecked());
+ CHECK_EQ(
+ result_obj->value(),
+ static_cast<int>(JSObject::NewElementsCapacity(test_value->value())));
+ test_value = Handle<Smi>(Smi::FromInt(1025), isolate);
+ result_obj = Handle<Smi>::cast(ft.Call(test_value).ToHandleChecked());
+ CHECK_EQ(
+ result_obj->value(),
+ static_cast<int>(JSObject::NewElementsCapacity(test_value->value())));
+}
+
+TEST(AllocateFunctionWithMapAndContext) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+
+ const int kNumParams = 1;
+ CodeAssemblerTester data(isolate, kNumParams);
+ PromiseBuiltinsAssembler m(data.state());
+
+ Node* const context = m.Parameter(kNumParams + 2);
+ Node* const native_context = m.LoadNativeContext(context);
+ Node* const promise =
+ m.AllocateAndInitJSPromise(context, m.UndefinedConstant());
+ Node* promise_context = m.CreatePromiseResolvingFunctionsContext(
+ promise, m.BooleanConstant(false), native_context);
+ Node* resolve_info =
+ m.LoadContextElement(native_context, Context::PROMISE_RESOLVE_SHARED_FUN);
+ Node* const map = m.LoadContextElement(
+ native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
+ Node* const resolve =
+ m.AllocateFunctionWithMapAndContext(map, resolve_info, promise_context);
+ m.Return(resolve);
+
+ Handle<Code> code = data.GenerateCode();
+ CHECK(!code.is_null());
+
+ FunctionTester ft(code, kNumParams);
+ Handle<Object> result_obj =
+ ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
+ CHECK(result_obj->IsJSFunction());
+ Handle<JSFunction> fun = Handle<JSFunction>::cast(result_obj);
+ CHECK_EQ(isolate->heap()->empty_fixed_array(), fun->properties());
+ CHECK_EQ(isolate->heap()->empty_fixed_array(), fun->elements());
+ CHECK_EQ(isolate->heap()->empty_literals_array(), fun->literals());
+ CHECK_EQ(isolate->heap()->the_hole_value(), fun->prototype_or_initial_map());
+ CHECK_EQ(*isolate->promise_resolve_shared_fun(), fun->shared());
+ CHECK_EQ(isolate->promise_resolve_shared_fun()->code(), fun->code());
+ CHECK_EQ(isolate->heap()->undefined_value(), fun->next_function_link());
+}
+
+TEST(CreatePromiseGetCapabilitiesExecutorContext) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+
+ const int kNumParams = 1;
+ CodeAssemblerTester data(isolate, kNumParams);
+ PromiseBuiltinsAssembler m(data.state());
+
+ Node* const context = m.Parameter(kNumParams + 2);
+ Node* const native_context = m.LoadNativeContext(context);
+
+ Node* const map = m.LoadRoot(Heap::kJSPromiseCapabilityMapRootIndex);
+ Node* const capability = m.AllocateJSObjectFromMap(map);
+ m.StoreObjectFieldNoWriteBarrier(
+ capability, JSPromiseCapability::kPromiseOffset, m.UndefinedConstant());
+ m.StoreObjectFieldNoWriteBarrier(
+ capability, JSPromiseCapability::kResolveOffset, m.UndefinedConstant());
+ m.StoreObjectFieldNoWriteBarrier(
+ capability, JSPromiseCapability::kRejectOffset, m.UndefinedConstant());
+ Node* const executor_context =
+ m.CreatePromiseGetCapabilitiesExecutorContext(capability, native_context);
+ m.Return(executor_context);
+
+ Handle<Code> code = data.GenerateCode();
+ CHECK(!code.is_null());
+
+ FunctionTester ft(code, kNumParams);
+ Handle<Object> result_obj =
+ ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
+ CHECK(result_obj->IsContext());
+ Handle<Context> context_js = Handle<Context>::cast(result_obj);
+ CHECK_EQ(PromiseBuiltinsAssembler::kCapabilitiesContextLength,
+ context_js->length());
+ CHECK_EQ(isolate->native_context()->closure(), context_js->closure());
+ CHECK_EQ(isolate->heap()->the_hole_value(), context_js->extension());
+ CHECK_EQ(*isolate->native_context(), context_js->native_context());
+ CHECK(context_js->get(PromiseBuiltinsAssembler::kCapabilitySlot)
+ ->IsJSPromiseCapability());
+}
+
+TEST(NewPromiseCapability) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+
+ { // Builtin Promise
+ const int kNumParams = 1;
+ CodeAssemblerTester data(isolate, kNumParams);
+ PromiseBuiltinsAssembler m(data.state());
+
+ Node* const context = m.Parameter(kNumParams + 2);
+ Node* const native_context = m.LoadNativeContext(context);
+ Node* const promise_constructor =
+ m.LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
+
+ Node* const capability =
+ m.NewPromiseCapability(context, promise_constructor);
+ m.Return(capability);
+
+ Handle<Code> code = data.GenerateCode();
+ FunctionTester ft(code, kNumParams);
+
+ Handle<Object> result_obj =
+ ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
+ CHECK(result_obj->IsJSPromiseCapability());
+ Handle<JSPromiseCapability> result =
+ Handle<JSPromiseCapability>::cast(result_obj);
+
+ CHECK(result->promise()->IsJSPromise());
+ CHECK(result->resolve()->IsJSFunction());
+ CHECK(result->reject()->IsJSFunction());
+ CHECK_EQ(isolate->native_context()->promise_resolve_shared_fun(),
+ JSFunction::cast(result->resolve())->shared());
+ CHECK_EQ(isolate->native_context()->promise_reject_shared_fun(),
+ JSFunction::cast(result->reject())->shared());
+
+ Handle<JSFunction> callbacks[] = {
+ handle(JSFunction::cast(result->resolve())),
+ handle(JSFunction::cast(result->reject()))};
+
+ for (auto&& callback : callbacks) {
+ Handle<Context> context(Context::cast(callback->context()));
+ CHECK_EQ(isolate->native_context()->closure(), context->closure());
+ CHECK_EQ(isolate->heap()->the_hole_value(), context->extension());
+ CHECK_EQ(*isolate->native_context(), context->native_context());
+ CHECK_EQ(PromiseBuiltinsAssembler::kPromiseContextLength,
+ context->length());
+ CHECK_EQ(context->get(PromiseBuiltinsAssembler::kPromiseSlot),
+ result->promise());
+ }
+ }
+
+ { // Custom Promise
+ const int kNumParams = 2;
+ CodeAssemblerTester data(isolate, kNumParams);
+ PromiseBuiltinsAssembler m(data.state());
+
+ Node* const context = m.Parameter(kNumParams + 2);
+
+ Node* const constructor = m.Parameter(1);
+ Node* const capability = m.NewPromiseCapability(context, constructor);
+ m.Return(capability);
+
+ Handle<Code> code = data.GenerateCode();
+ FunctionTester ft(code, kNumParams);
+
+ Handle<JSFunction> constructor_fn =
+ Handle<JSFunction>::cast(v8::Utils::OpenHandle(*CompileRun(
+ "(function FakePromise(executor) {"
+ " var self = this;"
+ " function resolve(value) { self.resolvedValue = value; }"
+ " function reject(reason) { self.rejectedReason = reason; }"
+ " executor(resolve, reject);"
+ "})")));
+
+ Handle<Object> result_obj =
+ ft.Call(isolate->factory()->undefined_value(), constructor_fn)
+ .ToHandleChecked();
+ CHECK(result_obj->IsJSPromiseCapability());
+ Handle<JSPromiseCapability> result =
+ Handle<JSPromiseCapability>::cast(result_obj);
+
+ CHECK(result->promise()->IsJSObject());
+ Handle<JSObject> promise(JSObject::cast(result->promise()));
+ CHECK_EQ(constructor_fn->prototype_or_initial_map(), promise->map());
+ CHECK(result->resolve()->IsJSFunction());
+ CHECK(result->reject()->IsJSFunction());
+
+ Handle<String> resolved_str =
+ isolate->factory()->NewStringFromAsciiChecked("resolvedStr");
+ Handle<String> rejected_str =
+ isolate->factory()->NewStringFromAsciiChecked("rejectedStr");
+
+ Handle<Object> argv1[] = {resolved_str};
+ Handle<Object> ret =
+ Execution::Call(isolate, handle(result->resolve(), isolate),
+ isolate->factory()->undefined_value(), 1, argv1)
+ .ToHandleChecked();
+
+ Handle<Object> prop1 =
+ JSReceiver::GetProperty(isolate, promise, "resolvedValue")
+ .ToHandleChecked();
+ CHECK_EQ(*resolved_str, *prop1);
+
+ Handle<Object> argv2[] = {rejected_str};
+ ret = Execution::Call(isolate, handle(result->reject(), isolate),
+ isolate->factory()->undefined_value(), 1, argv2)
+ .ToHandleChecked();
+ Handle<Object> prop2 =
+ JSReceiver::GetProperty(isolate, promise, "rejectedReason")
+ .ToHandleChecked();
+ CHECK_EQ(*rejected_str, *prop2);
+ }
+}
+
+TEST(DirectMemoryTest8BitWord32Immediate) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+ typedef CodeAssemblerLabel Label;
+
+ const int kNumParams = 0;
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeStubAssembler m(data.state());
+ int8_t buffer[] = {1, 2, 4, 8, 17, 33, 65, 127};
+ const int element_count = 8;
+ Label bad(&m);
+
+ Node* buffer_node = m.IntPtrConstant(reinterpret_cast<intptr_t>(buffer));
+ for (size_t i = 0; i < element_count; ++i) {
+ for (size_t j = 0; j < element_count; ++j) {
+ Node* loaded = m.LoadBufferObject(buffer_node, static_cast<int>(i),
+ MachineType::Uint8());
+ Node* masked = m.Word32And(loaded, m.Int32Constant(buffer[j]));
+ if ((buffer[j] & buffer[i]) != 0) {
+ m.GotoIf(m.Word32Equal(masked, m.Int32Constant(0)), &bad);
+ } else {
+ m.GotoIf(m.Word32NotEqual(masked, m.Int32Constant(0)), &bad);
+ }
+ }
+ }
+
+ m.Return(m.SmiConstant(1));
+
+ m.Bind(&bad);
+ m.Return(m.SmiConstant(0));
+
+ Handle<Code> code = data.GenerateCode();
+ CHECK(!code.is_null());
+ FunctionTester ft(code, kNumParams);
+ CHECK_EQ(1, Handle<Smi>::cast(ft.Call().ToHandleChecked())->value());
+}
+
+TEST(DirectMemoryTest16BitWord32Immediate) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+ typedef CodeAssemblerLabel Label;
+
+ const int kNumParams = 0;
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeStubAssembler m(data.state());
+ int16_t buffer[] = {156, 2234, 4544, 8444, 1723, 3888, 658, 1278};
+ const int element_count = 8;
+ Label bad(&m);
+
+ Node* buffer_node = m.IntPtrConstant(reinterpret_cast<intptr_t>(buffer));
+ for (size_t i = 0; i < element_count; ++i) {
+ for (size_t j = 0; j < element_count; ++j) {
+ Node* loaded =
+ m.LoadBufferObject(buffer_node, static_cast<int>(i * sizeof(int16_t)),
+ MachineType::Uint16());
+ Node* masked = m.Word32And(loaded, m.Int32Constant(buffer[j]));
+ if ((buffer[j] & buffer[i]) != 0) {
+ m.GotoIf(m.Word32Equal(masked, m.Int32Constant(0)), &bad);
+ } else {
+ m.GotoIf(m.Word32NotEqual(masked, m.Int32Constant(0)), &bad);
+ }
+ }
+ }
+
+ m.Return(m.SmiConstant(1));
+
+ m.Bind(&bad);
+ m.Return(m.SmiConstant(0));
+
+ Handle<Code> code = data.GenerateCode();
+ CHECK(!code.is_null());
+ FunctionTester ft(code, kNumParams);
+ CHECK_EQ(1, Handle<Smi>::cast(ft.Call().ToHandleChecked())->value());
+}
+
+TEST(DirectMemoryTest8BitWord32) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+ typedef CodeAssemblerLabel Label;
+
+ const int kNumParams = 0;
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeStubAssembler m(data.state());
+ int8_t buffer[] = {1, 2, 4, 8, 17, 33, 65, 127, 67, 38};
+ const int element_count = 10;
+ Label bad(&m);
+ Node* constants[element_count];
+
+ Node* buffer_node = m.IntPtrConstant(reinterpret_cast<intptr_t>(buffer));
+ for (size_t i = 0; i < element_count; ++i) {
+ constants[i] = m.LoadBufferObject(buffer_node, static_cast<int>(i),
+ MachineType::Uint8());
+ }
+
+ for (size_t i = 0; i < element_count; ++i) {
+ for (size_t j = 0; j < element_count; ++j) {
+ Node* loaded = m.LoadBufferObject(buffer_node, static_cast<int>(i),
+ MachineType::Uint8());
+ Node* masked = m.Word32And(loaded, constants[j]);
+ if ((buffer[j] & buffer[i]) != 0) {
+ m.GotoIf(m.Word32Equal(masked, m.Int32Constant(0)), &bad);
+ } else {
+ m.GotoIf(m.Word32NotEqual(masked, m.Int32Constant(0)), &bad);
+ }
+
+ masked = m.Word32And(constants[i], constants[j]);
+ if ((buffer[j] & buffer[i]) != 0) {
+ m.GotoIf(m.Word32Equal(masked, m.Int32Constant(0)), &bad);
+ } else {
+ m.GotoIf(m.Word32NotEqual(masked, m.Int32Constant(0)), &bad);
+ }
+ }
+ }
+
+ m.Return(m.SmiConstant(1));
+
+ m.Bind(&bad);
+ m.Return(m.SmiConstant(0));
+
+ Handle<Code> code = data.GenerateCode();
+ CHECK(!code.is_null());
+ FunctionTester ft(code, kNumParams);
+ CHECK_EQ(1, Handle<Smi>::cast(ft.Call().ToHandleChecked())->value());
+}
+
+TEST(DirectMemoryTest16BitWord32) {
+ Isolate* isolate(CcTest::InitIsolateOnce());
+ typedef CodeAssemblerLabel Label;
+
+ const int kNumParams = 0;
+ CodeAssemblerTester data(isolate, kNumParams);
+ CodeStubAssembler m(data.state());
+ int16_t buffer[] = {1, 2, 4, 8, 12345, 33, 65, 255, 67, 3823};
+ const int element_count = 10;
+ Label bad(&m);
+ Node* constants[element_count];
+
+ Node* buffer_node1 = m.IntPtrConstant(reinterpret_cast<intptr_t>(buffer));
+ for (size_t i = 0; i < element_count; ++i) {
+ constants[i] =
+ m.LoadBufferObject(buffer_node1, static_cast<int>(i * sizeof(int16_t)),
+ MachineType::Uint16());
+ }
+ Node* buffer_node2 = m.IntPtrConstant(reinterpret_cast<intptr_t>(buffer));
+
+ for (size_t i = 0; i < element_count; ++i) {
+ for (size_t j = 0; j < element_count; ++j) {
+ Node* loaded = m.LoadBufferObject(buffer_node1,
+ static_cast<int>(i * sizeof(int16_t)),
+ MachineType::Uint16());
+ Node* masked = m.Word32And(loaded, constants[j]);
+ if ((buffer[j] & buffer[i]) != 0) {
+ m.GotoIf(m.Word32Equal(masked, m.Int32Constant(0)), &bad);
+ } else {
+ m.GotoIf(m.Word32NotEqual(masked, m.Int32Constant(0)), &bad);
+ }
+
+ // Force a memory access relative to a high-number register.
+ loaded = m.LoadBufferObject(buffer_node2,
+ static_cast<int>(i * sizeof(int16_t)),
+ MachineType::Uint16());
+ masked = m.Word32And(loaded, constants[j]);
+ if ((buffer[j] & buffer[i]) != 0) {
+ m.GotoIf(m.Word32Equal(masked, m.Int32Constant(0)), &bad);
+ } else {
+ m.GotoIf(m.Word32NotEqual(masked, m.Int32Constant(0)), &bad);
+ }
+
+ masked = m.Word32And(constants[i], constants[j]);
+ if ((buffer[j] & buffer[i]) != 0) {
+ m.GotoIf(m.Word32Equal(masked, m.Int32Constant(0)), &bad);
+ } else {
+ m.GotoIf(m.Word32NotEqual(masked, m.Int32Constant(0)), &bad);
+ }
+ }
+ }
+
+ m.Return(m.SmiConstant(1));
+
+ m.Bind(&bad);
+ m.Return(m.SmiConstant(0));
+
+ Handle<Code> code = data.GenerateCode();
+ CHECK(!code.is_null());
+ FunctionTester ft(code, kNumParams);
+ CHECK_EQ(1, Handle<Smi>::cast(ft.Call().ToHandleChecked())->value());
+}
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/cctest/test-compiler.cc b/deps/v8/test/cctest/test-compiler.cc
index ef7506b58f..7191ceb78e 100644
--- a/deps/v8/test/cctest/test-compiler.cc
+++ b/deps/v8/test/cctest/test-compiler.cc
@@ -35,6 +35,7 @@
#include "src/disasm.h"
#include "src/factory.h"
#include "src/interpreter/interpreter.h"
+#include "src/objects-inl.h"
#include "test/cctest/cctest.h"
using namespace v8::internal;
@@ -625,7 +626,6 @@ TEST(IgnitionEntryTrampolineSelfHealing) {
CcTest::InitializeVM();
FLAG_ignition = true;
Isolate* isolate = CcTest::i_isolate();
- isolate->interpreter()->Initialize();
v8::HandleScope scope(CcTest::isolate());
CompileRun(
diff --git a/deps/v8/test/cctest/test-conversions.cc b/deps/v8/test/cctest/test-conversions.cc
index 2fee58a46d..65cd96e0df 100644
--- a/deps/v8/test/cctest/test-conversions.cc
+++ b/deps/v8/test/cctest/test-conversions.cc
@@ -444,3 +444,61 @@ TEST(NoHandlesForTryNumberToSize) {
}
}
}
+
+TEST(TryNumberToSizeWithMaxSizePlusOne) {
+ i::Isolate* isolate = CcTest::i_isolate();
+ {
+ HandleScope scope(isolate);
+ // 1 << 64, larger than the limit of size_t.
+ double value = 18446744073709551616.0;
+ size_t result = 0;
+ Handle<HeapNumber> heap_number = isolate->factory()->NewHeapNumber(value);
+ CHECK(!TryNumberToSize(*heap_number, &result));
+ }
+}
+
+TEST(PositiveNumberToUint32) {
+ i::Isolate* isolate = CcTest::i_isolate();
+ i::Factory* factory = isolate->factory();
+ uint32_t max = std::numeric_limits<uint32_t>::max();
+ HandleScope scope(isolate);
+ // Test Smi conversions.
+ Handle<Object> number = handle(Smi::FromInt(0), isolate);
+ CHECK_EQ(PositiveNumberToUint32(*number), 0u);
+ number = handle(Smi::FromInt(-1), isolate);
+ CHECK_EQ(PositiveNumberToUint32(*number), 0u);
+ number = handle(Smi::FromInt(-1), isolate);
+ CHECK_EQ(PositiveNumberToUint32(*number), 0u);
+ number = handle(Smi::FromInt(Smi::kMinValue), isolate);
+ CHECK_EQ(PositiveNumberToUint32(*number), 0u);
+ number = handle(Smi::FromInt(Smi::kMaxValue), isolate);
+ CHECK_EQ(PositiveNumberToUint32(*number),
+ static_cast<uint32_t>(Smi::kMaxValue));
+ // Test Double conversions.
+ number = factory->NewHeapNumber(0.0);
+ CHECK_EQ(PositiveNumberToUint32(*number), 0u);
+ number = factory->NewHeapNumber(0.999);
+ CHECK_EQ(PositiveNumberToUint32(*number), 0u);
+ number = factory->NewHeapNumber(1.999);
+ CHECK_EQ(PositiveNumberToUint32(*number), 1u);
+ number = factory->NewHeapNumber(-12.0);
+ CHECK_EQ(PositiveNumberToUint32(*number), 0u);
+ number = factory->NewHeapNumber(12000.0);
+ CHECK_EQ(PositiveNumberToUint32(*number), 12000u);
+ number = factory->NewHeapNumber(static_cast<double>(Smi::kMaxValue) + 1);
+ CHECK_EQ(PositiveNumberToUint32(*number),
+ static_cast<uint32_t>(Smi::kMaxValue) + 1);
+ number = factory->NewHeapNumber(max);
+ CHECK_EQ(PositiveNumberToUint32(*number), max);
+ number = factory->NewHeapNumber(static_cast<double>(max) * 1000);
+ CHECK_EQ(PositiveNumberToUint32(*number), max);
+ number = factory->NewHeapNumber(std::numeric_limits<double>::max());
+ CHECK_EQ(PositiveNumberToUint32(*number), max);
+ number = factory->NewHeapNumber(std::numeric_limits<double>::infinity());
+ CHECK_EQ(PositiveNumberToUint32(*number), max);
+ number =
+ factory->NewHeapNumber(-1.0 * std::numeric_limits<double>::infinity());
+ CHECK_EQ(PositiveNumberToUint32(*number), 0u);
+ number = factory->NewHeapNumber(std::nan(""));
+ CHECK_EQ(PositiveNumberToUint32(*number), 0u);
+}
diff --git a/deps/v8/test/cctest/test-cpu-profiler.cc b/deps/v8/test/cctest/test-cpu-profiler.cc
index a69dd4cad4..6ec71a2ab3 100644
--- a/deps/v8/test/cctest/test-cpu-profiler.cc
+++ b/deps/v8/test/cctest/test-cpu-profiler.cc
@@ -1575,6 +1575,7 @@ TEST(JsNativeJsRuntimeJsSampleMultiple) {
static const char* inlining_test_source =
"%NeverOptimizeFunction(action);\n"
"%NeverOptimizeFunction(start);\n"
+ "level1()\n"
"%OptimizeFunctionOnNextCall(level1);\n"
"%OptimizeFunctionOnNextCall(level2);\n"
"%OptimizeFunctionOnNextCall(level3);\n"
@@ -1871,15 +1872,20 @@ TEST(CollectDeoptEvents) {
{
const char* branch[] = {"", "opt_function0", "opt_function0"};
- CHECK_EQ(reason(i::DeoptimizeReason::kNotAHeapNumber),
- GetBranchDeoptReason(env, iprofile, branch, arraysize(branch)));
+ const char* deopt_reason =
+ GetBranchDeoptReason(env, iprofile, branch, arraysize(branch));
+ if (deopt_reason != reason(i::DeoptimizeReason::kNotAHeapNumber) &&
+ deopt_reason != reason(i::DeoptimizeReason::kNotASmi)) {
+ FATAL(deopt_reason);
+ }
}
{
const char* branch[] = {"", "opt_function1", "opt_function1"};
const char* deopt_reason =
GetBranchDeoptReason(env, iprofile, branch, arraysize(branch));
if (deopt_reason != reason(i::DeoptimizeReason::kNaN) &&
- deopt_reason != reason(i::DeoptimizeReason::kLostPrecisionOrNaN)) {
+ deopt_reason != reason(i::DeoptimizeReason::kLostPrecisionOrNaN) &&
+ deopt_reason != reason(i::DeoptimizeReason::kNotASmi)) {
FATAL(deopt_reason);
}
}
diff --git a/deps/v8/test/cctest/test-debug.cc b/deps/v8/test/cctest/test-debug.cc
index 3b43d9d11f..54904f9b84 100644
--- a/deps/v8/test/cctest/test-debug.cc
+++ b/deps/v8/test/cctest/test-debug.cc
@@ -30,8 +30,6 @@
#include "src/v8.h"
#include "src/api.h"
-#include "src/base/platform/condition-variable.h"
-#include "src/base/platform/platform.h"
#include "src/compilation-cache.h"
#include "src/debug/debug-interface.h"
#include "src/debug/debug.h"
@@ -40,11 +38,6 @@
#include "src/utils.h"
#include "test/cctest/cctest.h"
-using ::v8::base::Mutex;
-using ::v8::base::LockGuard;
-using ::v8::base::ConditionVariable;
-using ::v8::base::OS;
-using ::v8::base::Semaphore;
using ::v8::internal::EmbeddedVector;
using ::v8::internal::Object;
using ::v8::internal::Handle;
@@ -52,8 +45,6 @@ using ::v8::internal::Heap;
using ::v8::internal::JSGlobalProxy;
using ::v8::internal::Code;
using ::v8::internal::Debug;
-using ::v8::internal::CommandMessage;
-using ::v8::internal::CommandMessageQueue;
using ::v8::internal::StackFrame;
using ::v8::internal::StepAction;
using ::v8::internal::StepIn; // From StepAction enum
@@ -321,8 +312,8 @@ static void ChangeBreakOnExceptionFromJS(v8::Isolate* isolate, bool caught,
// Change break on exception using the native API call.
static void ChangeBreakOnExceptionFromAPI(
- v8::Isolate* isolate, v8::DebugInterface::ExceptionBreakState state) {
- v8::DebugInterface::ChangeBreakOnException(isolate, state);
+ v8::Isolate* isolate, v8::debug::ExceptionBreakState state) {
+ v8::debug::ChangeBreakOnException(isolate, state);
}
// Prepare to step to next break location.
@@ -408,9 +399,6 @@ void CheckDebuggerUnloaded(bool check_functions) {
// Check that the debugger has been fully unloaded.
static void CheckDebuggerUnloaded(v8::Isolate* isolate,
bool check_functions = false) {
- // Let debugger to unload itself synchronously
- v8::Debug::ProcessDebugMessages(isolate);
-
v8::internal::CheckDebuggerUnloaded(check_functions);
}
@@ -1612,20 +1600,6 @@ TEST(EnableDisableScriptBreakPoint) {
f->Call(context, env->Global(), 0, NULL).ToLocalChecked();
CHECK_EQ(2, break_point_hit_count);
- // Reload the script and get f again checking that the disabling survives.
- v8::Script::Compile(context, script, &origin)
- .ToLocalChecked()
- ->Run(context)
- .ToLocalChecked();
- f = v8::Local<v8::Function>::Cast(
- env->Global()->Get(context, v8_str(isolate, "f")).ToLocalChecked());
- f->Call(context, env->Global(), 0, NULL).ToLocalChecked();
- CHECK_EQ(2, break_point_hit_count);
-
- EnableScriptBreakPointFromJS(isolate, sbp);
- f->Call(context, env->Global(), 0, NULL).ToLocalChecked();
- CHECK_EQ(3, break_point_hit_count);
-
v8::Debug::SetDebugEventListener(isolate, nullptr);
CheckDebuggerUnloaded(isolate);
}
@@ -1683,100 +1657,6 @@ TEST(ConditionalScriptBreakPoint) {
}
CHECK_EQ(5, break_point_hit_count);
- // Reload the script and get f again checking that the condition survives.
- v8::Script::Compile(context, script, &origin)
- .ToLocalChecked()
- ->Run(context)
- .ToLocalChecked();
- f = v8::Local<v8::Function>::Cast(
- env->Global()
- ->Get(context, v8_str(env->GetIsolate(), "f"))
- .ToLocalChecked());
-
- break_point_hit_count = 0;
- for (int i = 0; i < 10; i++) {
- f->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked();
- }
- CHECK_EQ(5, break_point_hit_count);
-
- v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr);
- CheckDebuggerUnloaded(env->GetIsolate());
-}
-
-
-// Test that script break points survive when a script is reloaded.
-TEST(ScriptBreakPointReload) {
- break_point_hit_count = 0;
- DebugLocalContext env;
- v8::HandleScope scope(env->GetIsolate());
- env.ExposeDebug();
-
- v8::Debug::SetDebugEventListener(env->GetIsolate(),
- DebugEventBreakPointHitCount);
-
- v8::Local<v8::Context> context = env.context();
- v8::Local<v8::Function> f;
- v8::Local<v8::String> script = v8_str(env->GetIsolate(),
- "function f() {\n"
- " function h() {\n"
- " a = 0; // line 2\n"
- " }\n"
- " b = 1; // line 4\n"
- " return h();\n"
- "}");
-
- v8::ScriptOrigin origin_1 = v8::ScriptOrigin(v8_str(env->GetIsolate(), "1"));
- v8::ScriptOrigin origin_2 = v8::ScriptOrigin(v8_str(env->GetIsolate(), "2"));
-
- // Set a script break point before the script is loaded.
- SetScriptBreakPointByNameFromJS(env->GetIsolate(), "1", 2, 0);
-
- // Compile the script and get the function.
- v8::Script::Compile(context, script, &origin_1)
- .ToLocalChecked()
- ->Run(context)
- .ToLocalChecked();
- f = v8::Local<v8::Function>::Cast(
- env->Global()
- ->Get(context, v8_str(env->GetIsolate(), "f"))
- .ToLocalChecked());
-
- // Call f and check that the script break point is active.
- break_point_hit_count = 0;
- f->Call(context, env->Global(), 0, NULL).ToLocalChecked();
- CHECK_EQ(1, break_point_hit_count);
-
- // Compile the script again with a different script data and get the
- // function.
- v8::Script::Compile(context, script, &origin_2)
- .ToLocalChecked()
- ->Run(context)
- .ToLocalChecked();
- f = v8::Local<v8::Function>::Cast(
- env->Global()
- ->Get(context, v8_str(env->GetIsolate(), "f"))
- .ToLocalChecked());
-
- // Call f and check that no break points are set.
- break_point_hit_count = 0;
- f->Call(context, env->Global(), 0, NULL).ToLocalChecked();
- CHECK_EQ(0, break_point_hit_count);
-
- // Compile the script again and get the function.
- v8::Script::Compile(context, script, &origin_1)
- .ToLocalChecked()
- ->Run(context)
- .ToLocalChecked();
- f = v8::Local<v8::Function>::Cast(
- env->Global()
- ->Get(context, v8_str(env->GetIsolate(), "f"))
- .ToLocalChecked());
-
- // Call f and check that the script break point is active.
- break_point_hit_count = 0;
- f->Call(context, env->Global(), 0, NULL).ToLocalChecked();
- CHECK_EQ(1, break_point_hit_count);
-
v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr);
CheckDebuggerUnloaded(env->GetIsolate());
}
@@ -1807,9 +1687,6 @@ TEST(ScriptBreakPointMultiple) {
v8::ScriptOrigin origin = v8::ScriptOrigin(v8_str(env->GetIsolate(), "test"));
- // Set a script break point before the scripts are loaded.
- int sbp = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 1, 0);
-
// Compile the scripts with same script data and get the functions.
v8::Script::Compile(context, script_f, &origin)
.ToLocalChecked()
@@ -1828,6 +1705,8 @@ TEST(ScriptBreakPointMultiple) {
->Get(context, v8_str(env->GetIsolate(), "g"))
.ToLocalChecked());
+ int sbp = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 1, 0);
+
// Call f and g and check that the script break point is active.
break_point_hit_count = 0;
f->Call(context, env->Global(), 0, NULL).ToLocalChecked();
@@ -1883,17 +1762,17 @@ TEST(ScriptBreakPointLineOffset) {
v8::ScriptOrigin origin(v8_str(env->GetIsolate(), "test.html"),
v8::Integer::New(env->GetIsolate(), 7));
- // Set two script break points before the script is loaded.
- int sbp1 =
- SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 8, 0);
- int sbp2 =
- SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 9, 0);
-
// Compile the script and get the function.
v8::Script::Compile(context, script, &origin)
.ToLocalChecked()
->Run(context)
.ToLocalChecked();
+
+ int sbp1 =
+ SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 8, 0);
+ int sbp2 =
+ SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 9, 0);
+
f = v8::Local<v8::Function>::Cast(
env->Global()
->Get(context, v8_str(env->GetIsolate(), "f"))
@@ -1959,7 +1838,13 @@ TEST(ScriptBreakPointLine) {
" }\n"
" a=5; // line 12");
- // Set a couple script break point before the script is loaded.
+ // Compile the script and get the function.
+ break_point_hit_count = 0;
+ v8::ScriptOrigin origin(v8_str(env->GetIsolate(), "test.html"),
+ v8::Integer::New(env->GetIsolate(), 0));
+ v8::Local<v8::Script> compiled =
+ v8::Script::Compile(context, script, &origin).ToLocalChecked();
+
int sbp1 =
SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 0, -1);
int sbp2 =
@@ -1967,14 +1852,8 @@ TEST(ScriptBreakPointLine) {
int sbp3 =
SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 5, -1);
- // Compile the script and get the function.
- break_point_hit_count = 0;
- v8::ScriptOrigin origin(v8_str(env->GetIsolate(), "test.html"),
- v8::Integer::New(env->GetIsolate(), 0));
- v8::Script::Compile(context, script, &origin)
- .ToLocalChecked()
- ->Run(context)
- .ToLocalChecked();
+ compiled->Run(context).ToLocalChecked();
+
f = v8::Local<v8::Function>::Cast(
env->Global()
->Get(context, v8_str(env->GetIsolate(), "f"))
@@ -2020,39 +1899,21 @@ TEST(ScriptBreakPointLine) {
g->Call(context, env->Global(), 0, NULL).ToLocalChecked();
CHECK_EQ(0, break_point_hit_count);
- // Reload the script which should hit two break points.
- break_point_hit_count = 0;
- v8::Script::Compile(context, script, &origin)
- .ToLocalChecked()
- ->Run(context)
- .ToLocalChecked();
- CHECK_EQ(2, break_point_hit_count);
- CHECK_EQ(0, StrLength(last_function_hit));
-
// Set a break point in the code after the last function decleration.
int sbp6 =
SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 12, -1);
- // Reload the script which should hit three break points.
+ // Reloading the script should not hit any break points.
break_point_hit_count = 0;
v8::Script::Compile(context, script, &origin)
.ToLocalChecked()
->Run(context)
.ToLocalChecked();
- CHECK_EQ(3, break_point_hit_count);
- CHECK_EQ(0, StrLength(last_function_hit));
+ CHECK_EQ(0, break_point_hit_count);
- // Clear the last break points, and reload the script which should not hit any
- // break points.
ClearBreakPointFromJS(env->GetIsolate(), sbp1);
ClearBreakPointFromJS(env->GetIsolate(), sbp5);
ClearBreakPointFromJS(env->GetIsolate(), sbp6);
- break_point_hit_count = 0;
- v8::Script::Compile(context, script, &origin)
- .ToLocalChecked()
- ->Run(context)
- .ToLocalChecked();
- CHECK_EQ(0, break_point_hit_count);
v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr);
CheckDebuggerUnloaded(env->GetIsolate());
@@ -2094,17 +1955,9 @@ TEST(ScriptBreakPointLineTopLevel) {
f->Call(context, env->Global(), 0, NULL).ToLocalChecked();
CHECK_EQ(0, break_point_hit_count);
- // Recompile and run script and check that break point was hit.
+ // Recompile and run script and check that break point was not reapplied.
break_point_hit_count = 0;
CompileRunWithOrigin(script, "test.html");
- CHECK_EQ(1, break_point_hit_count);
-
- // Call f and check that there are still no break points.
- break_point_hit_count = 0;
- f = v8::Local<v8::Function>::Cast(
- env->Global()
- ->Get(context, v8_str(env->GetIsolate(), "f"))
- .ToLocalChecked());
CHECK_EQ(0, break_point_hit_count);
v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr);
@@ -2122,20 +1975,18 @@ TEST(ScriptBreakPointTopLevelCrash) {
v8::Debug::SetDebugEventListener(env->GetIsolate(),
DebugEventBreakPointHitCount);
- v8::Local<v8::String> script_source = v8_str(env->GetIsolate(),
- "function f() {\n"
- " return 0;\n"
- "}\n"
- "f()");
-
+ CompileRunWithOrigin(
+ "function f() {\n"
+ " return 0;\n"
+ "}\n",
+ "test.html");
int sbp1 =
- SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 3, -1);
- {
- v8::HandleScope scope(env->GetIsolate());
- break_point_hit_count = 0;
- CompileRunWithOrigin(script_source, "test.html");
- CHECK_EQ(1, break_point_hit_count);
- }
+ SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 1, -1);
+ break_point_hit_count = 0;
+
+ CompileRun("f();");
+
+ CHECK_EQ(1, break_point_hit_count);
int sbp2 =
SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 3, -1);
@@ -2492,171 +2343,6 @@ TEST(DebugEvaluateWithCodeGenerationDisallowed) {
}
-// Copies a C string to a 16-bit string. Does not check for buffer overflow.
-// Does not use the V8 engine to convert strings, so it can be used
-// in any thread. Returns the length of the string.
-int AsciiToUtf16(const char* input_buffer, uint16_t* output_buffer) {
- int i;
- for (i = 0; input_buffer[i] != '\0'; ++i) {
- // ASCII does not use chars > 127, but be careful anyway.
- output_buffer[i] = static_cast<unsigned char>(input_buffer[i]);
- }
- output_buffer[i] = 0;
- return i;
-}
-
-
-// Copies a 16-bit string to a C string by dropping the high byte of
-// each character. Does not check for buffer overflow.
-// Can be used in any thread. Requires string length as an input.
-int Utf16ToAscii(const uint16_t* input_buffer, int length,
- char* output_buffer, int output_len = -1) {
- if (output_len >= 0) {
- if (length > output_len - 1) {
- length = output_len - 1;
- }
- }
-
- for (int i = 0; i < length; ++i) {
- output_buffer[i] = static_cast<char>(input_buffer[i]);
- }
- output_buffer[length] = '\0';
- return length;
-}
-
-
-// We match parts of the message to get evaluate result int value.
-bool GetEvaluateStringResult(char *message, char* buffer, int buffer_size) {
- if (strstr(message, "\"command\":\"evaluate\"") == NULL) {
- return false;
- }
- const char* prefix = "\"text\":\"";
- char* pos1 = strstr(message, prefix);
- if (pos1 == NULL) {
- return false;
- }
- pos1 += strlen(prefix);
- char* pos2 = strchr(pos1, '"');
- if (pos2 == NULL) {
- return false;
- }
- Vector<char> buf(buffer, buffer_size);
- int len = static_cast<int>(pos2 - pos1);
- if (len > buffer_size - 1) {
- len = buffer_size - 1;
- }
- StrNCpy(buf, pos1, len);
- buffer[buffer_size - 1] = '\0';
- return true;
-}
-
-
-struct EvaluateResult {
- static const int kBufferSize = 20;
- char buffer[kBufferSize];
-};
-
-struct DebugProcessDebugMessagesData {
- static const int kArraySize = 5;
- int counter;
- EvaluateResult results[kArraySize];
-
- void reset() {
- counter = 0;
- }
- EvaluateResult* current() {
- return &results[counter % kArraySize];
- }
- void next() {
- counter++;
- }
-};
-
-DebugProcessDebugMessagesData process_debug_messages_data;
-
-static void DebugProcessDebugMessagesHandler(
- const v8::Debug::Message& message) {
- v8::Local<v8::String> json = message.GetJSON();
- v8::String::Utf8Value utf8(json);
- EvaluateResult* array_item = process_debug_messages_data.current();
-
- bool res = GetEvaluateStringResult(*utf8,
- array_item->buffer,
- EvaluateResult::kBufferSize);
- if (res) {
- process_debug_messages_data.next();
- }
-}
-
-
-// Test that the evaluation of expressions works even from ProcessDebugMessages
-// i.e. with empty stack.
-TEST(DebugEvaluateWithoutStack) {
- DebugLocalContext env;
- v8::Debug::SetMessageHandler(env->GetIsolate(),
- DebugProcessDebugMessagesHandler);
- v8::HandleScope scope(env->GetIsolate());
-
- const char* source =
- "var v1 = 'Pinguin';\n function getAnimal() { return 'Capy' + 'bara'; }";
-
- v8::Local<v8::Context> context = env.context();
- v8::Script::Compile(context, v8_str(env->GetIsolate(), source))
- .ToLocalChecked()
- ->Run(context)
- .ToLocalChecked();
-
- v8::Debug::ProcessDebugMessages(env->GetIsolate());
-
- const int kBufferSize = 1000;
- uint16_t buffer[kBufferSize];
-
- const char* command_111 = "{\"seq\":111,"
- "\"type\":\"request\","
- "\"command\":\"evaluate\","
- "\"arguments\":{"
- " \"global\":true,"
- " \"expression\":\"v1\",\"disable_break\":true"
- "}}";
-
- v8::Isolate* isolate = CcTest::isolate();
- v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_111, buffer));
-
- const char* command_112 = "{\"seq\":112,"
- "\"type\":\"request\","
- "\"command\":\"evaluate\","
- "\"arguments\":{"
- " \"global\":true,"
- " \"expression\":\"getAnimal()\",\"disable_break\":true"
- "}}";
-
- v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_112, buffer));
-
- const char* command_113 = "{\"seq\":113,"
- "\"type\":\"request\","
- "\"command\":\"evaluate\","
- "\"arguments\":{"
- " \"global\":true,"
- " \"expression\":\"239 + 566\",\"disable_break\":true"
- "}}";
-
- v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_113, buffer));
-
- v8::Debug::ProcessDebugMessages(isolate);
-
- CHECK_EQ(3, process_debug_messages_data.counter);
-
- CHECK_EQ(strcmp("Pinguin", process_debug_messages_data.results[0].buffer), 0);
- CHECK_EQ(strcmp("Capybara", process_debug_messages_data.results[1].buffer),
- 0);
- CHECK_EQ(strcmp("805", process_debug_messages_data.results[2].buffer), 0);
-
- v8::Debug::SetMessageHandler(env->GetIsolate(), nullptr);
- v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr);
- CheckDebuggerUnloaded(env->GetIsolate());
-}
-
-
// Simple test of the stepping mechanism using only store ICs.
TEST(DebugStepLinear) {
DebugLocalContext env;
@@ -3815,15 +3501,16 @@ TEST(PauseInScript) {
const char* src = "(function (evt) {})";
const char* script_name = "StepInHandlerTest";
- // Set breakpoint in the script.
- SetScriptBreakPointByNameFromJS(env->GetIsolate(), script_name, 0, -1);
- break_point_hit_count = 0;
-
v8::ScriptOrigin origin(v8_str(env->GetIsolate(), script_name),
v8::Integer::New(env->GetIsolate(), 0));
v8::Local<v8::Script> script =
v8::Script::Compile(context, v8_str(env->GetIsolate(), src), &origin)
.ToLocalChecked();
+
+ // Set breakpoint in the script.
+ SetScriptBreakPointByNameFromJS(env->GetIsolate(), script_name, 0, -1);
+ break_point_hit_count = 0;
+
v8::Local<v8::Value> r = script->Run(context).ToLocalChecked();
CHECK(r->IsFunction());
@@ -3995,7 +3682,7 @@ TEST(BreakOnException) {
DebugEventCounterClear();
MessageCallbackCountClear();
ChangeBreakOnExceptionFromAPI(env->GetIsolate(),
- v8::DebugInterface::NoBreakOnException);
+ v8::debug::NoBreakOnException);
caught->Call(context, env->Global(), 0, NULL).ToLocalChecked();
DebugEventCounterCheck(0, 0, 0);
CHECK(notCaught->Call(context, env->Global(), 0, NULL).IsEmpty());
@@ -4009,7 +3696,7 @@ TEST(BreakOnException) {
DebugEventCounterClear();
MessageCallbackCountClear();
ChangeBreakOnExceptionFromAPI(env->GetIsolate(),
- v8::DebugInterface::BreakOnUncaughtException);
+ v8::debug::BreakOnUncaughtException);
caught->Call(context, env->Global(), 0, NULL).ToLocalChecked();
DebugEventCounterCheck(0, 0, 0);
CHECK(notCaught->Call(context, env->Global(), 0, NULL).IsEmpty());
@@ -4023,7 +3710,7 @@ TEST(BreakOnException) {
DebugEventCounterClear();
MessageCallbackCountClear();
ChangeBreakOnExceptionFromAPI(env->GetIsolate(),
- v8::DebugInterface::BreakOnAnyException);
+ v8::debug::BreakOnAnyException);
caught->Call(context, env->Global(), 0, NULL).ToLocalChecked();
DebugEventCounterCheck(1, 0, 0);
CHECK(notCaught->Call(context, env->Global(), 0, NULL).IsEmpty());
@@ -4302,7 +3989,6 @@ TEST(DebugBreak) {
// Set the debug break flag.
v8::Debug::DebugBreak(env->GetIsolate());
- CHECK(v8::Debug::CheckDebugBreak(env->GetIsolate()));
// Call all functions with different argument count.
break_point_hit_count = 0;
@@ -4338,9 +4024,7 @@ TEST(DisableBreak) {
// Set, test and cancel debug break.
v8::Debug::DebugBreak(env->GetIsolate());
- CHECK(v8::Debug::CheckDebugBreak(env->GetIsolate()));
v8::Debug::CancelDebugBreak(env->GetIsolate());
- CHECK(!v8::Debug::CheckDebugBreak(env->GetIsolate()));
// Set the debug break flag.
v8::Debug::DebugBreak(env->GetIsolate());
@@ -4353,7 +4037,7 @@ TEST(DisableBreak) {
{
v8::Debug::DebugBreak(env->GetIsolate());
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(env->GetIsolate());
- v8::internal::DisableBreak disable_break(isolate->debug(), true);
+ v8::internal::DisableBreak disable_break(isolate->debug());
f->Call(context, env->Global(), 0, NULL).ToLocalChecked();
CHECK_EQ(1, break_point_hit_count);
}
@@ -4942,787 +4626,10 @@ TEST(NoHiddenProperties) {
}
-// Multithreaded tests of JSON debugger protocol
-
-// Support classes
-
-// Provides synchronization between N threads, where N is a template parameter.
-// The Wait() call blocks a thread until it is called for the Nth time, then all
-// calls return. Each ThreadBarrier object can only be used once.
-template <int N>
-class ThreadBarrier final {
- public:
- ThreadBarrier() : num_blocked_(0) {}
-
- ~ThreadBarrier() {
- LockGuard<Mutex> lock_guard(&mutex_);
- if (num_blocked_ != 0) {
- CHECK_EQ(N, num_blocked_);
- }
- }
-
- void Wait() {
- LockGuard<Mutex> lock_guard(&mutex_);
- CHECK_LT(num_blocked_, N);
- num_blocked_++;
- if (N == num_blocked_) {
- // Signal and unblock all waiting threads.
- cv_.NotifyAll();
- printf("BARRIER\n\n");
- fflush(stdout);
- } else { // Wait for the semaphore.
- while (num_blocked_ < N) {
- cv_.Wait(&mutex_);
- }
- }
- CHECK_EQ(N, num_blocked_);
- }
-
- private:
- ConditionVariable cv_;
- Mutex mutex_;
- int num_blocked_;
-
- STATIC_ASSERT(N > 0);
-
- DISALLOW_COPY_AND_ASSIGN(ThreadBarrier);
-};
-
-
-// A set containing enough barriers and semaphores for any of the tests.
-class Barriers {
- public:
- Barriers() : semaphore_1(0), semaphore_2(0) {}
- ThreadBarrier<2> barrier_1;
- ThreadBarrier<2> barrier_2;
- ThreadBarrier<2> barrier_3;
- ThreadBarrier<2> barrier_4;
- ThreadBarrier<2> barrier_5;
- v8::base::Semaphore semaphore_1;
- v8::base::Semaphore semaphore_2;
-};
-
-
-// We match parts of the message to decide if it is a break message.
-bool IsBreakEventMessage(char *message) {
- const char* type_event = "\"type\":\"event\"";
- const char* event_break = "\"event\":\"break\"";
- // Does the message contain both type:event and event:break?
- return strstr(message, type_event) != NULL &&
- strstr(message, event_break) != NULL;
-}
-
-
-// We match parts of the message to decide if it is a exception message.
-bool IsExceptionEventMessage(char *message) {
- const char* type_event = "\"type\":\"event\"";
- const char* event_exception = "\"event\":\"exception\"";
- // Does the message contain both type:event and event:exception?
- return strstr(message, type_event) != NULL &&
- strstr(message, event_exception) != NULL;
-}
-
-
-// We match the message wether it is an evaluate response message.
-bool IsEvaluateResponseMessage(char* message) {
- const char* type_response = "\"type\":\"response\"";
- const char* command_evaluate = "\"command\":\"evaluate\"";
- // Does the message contain both type:response and command:evaluate?
- return strstr(message, type_response) != NULL &&
- strstr(message, command_evaluate) != NULL;
-}
-
-
-static int StringToInt(const char* s) {
- return atoi(s); // NOLINT
-}
-
-
-// We match parts of the message to get evaluate result int value.
-int GetEvaluateIntResult(char *message) {
- const char* value = "\"value\":";
- char* pos = strstr(message, value);
- if (pos == NULL) {
- return -1;
- }
- int res = -1;
- res = StringToInt(pos + strlen(value));
- return res;
-}
-
-
-// We match parts of the message to get hit breakpoint id.
-int GetBreakpointIdFromBreakEventMessage(char *message) {
- const char* breakpoints = "\"breakpoints\":[";
- char* pos = strstr(message, breakpoints);
- if (pos == NULL) {
- return -1;
- }
- int res = -1;
- res = StringToInt(pos + strlen(breakpoints));
- return res;
-}
-
-
-// We match parts of the message to get total frames number.
-int GetTotalFramesInt(char *message) {
- const char* prefix = "\"totalFrames\":";
- char* pos = strstr(message, prefix);
- if (pos == NULL) {
- return -1;
- }
- pos += strlen(prefix);
- int res = StringToInt(pos);
- return res;
-}
-
-
-// We match parts of the message to get source line.
-int GetSourceLineFromBreakEventMessage(char *message) {
- const char* source_line = "\"sourceLine\":";
- char* pos = strstr(message, source_line);
- if (pos == NULL) {
- return -1;
- }
- int res = -1;
- res = StringToInt(pos + strlen(source_line));
- return res;
-}
-
-
-/* Test MessageQueues */
-/* Tests the message queues that hold debugger commands and
- * response messages to the debugger. Fills queues and makes
- * them grow.
- */
-Barriers message_queue_barriers;
-
-// This is the debugger thread, that executes no v8 calls except
-// placing JSON debugger commands in the queue.
-class MessageQueueDebuggerThread : public v8::base::Thread {
- public:
- MessageQueueDebuggerThread()
- : Thread(Options("MessageQueueDebuggerThread")) {}
- void Run();
-};
-
-
-static void MessageHandler(const v8::Debug::Message& message) {
- v8::Local<v8::String> json = message.GetJSON();
- v8::String::Utf8Value utf8(json);
- if (IsBreakEventMessage(*utf8)) {
- // Lets test script wait until break occurs to send commands.
- // Signals when a break is reported.
- message_queue_barriers.semaphore_2.Signal();
- }
-
- // Allow message handler to block on a semaphore, to test queueing of
- // messages while blocked.
- message_queue_barriers.semaphore_1.Wait();
-}
-
-
-void MessageQueueDebuggerThread::Run() {
- const int kBufferSize = 1000;
- uint16_t buffer_1[kBufferSize];
- uint16_t buffer_2[kBufferSize];
- const char* command_1 =
- "{\"seq\":117,"
- "\"type\":\"request\","
- "\"command\":\"evaluate\","
- "\"arguments\":{\"expression\":\"1+2\"}}";
- const char* command_2 =
- "{\"seq\":118,"
- "\"type\":\"request\","
- "\"command\":\"evaluate\","
- "\"arguments\":{\"expression\":\"1+a\"}}";
- const char* command_3 =
- "{\"seq\":119,"
- "\"type\":\"request\","
- "\"command\":\"evaluate\","
- "\"arguments\":{\"expression\":\"c.d * b\"}}";
- const char* command_continue =
- "{\"seq\":106,"
- "\"type\":\"request\","
- "\"command\":\"continue\"}";
- const char* command_single_step =
- "{\"seq\":107,"
- "\"type\":\"request\","
- "\"command\":\"continue\","
- "\"arguments\":{\"stepaction\":\"next\"}}";
-
- /* Interleaved sequence of actions by the two threads:*/
- // Main thread compiles and runs source_1
- message_queue_barriers.semaphore_1.Signal();
- message_queue_barriers.barrier_1.Wait();
- // Post 6 commands, filling the command queue and making it expand.
- // These calls return immediately, but the commands stay on the queue
- // until the execution of source_2.
- // Note: AsciiToUtf16 executes before SendCommand, so command is copied
- // to buffer before buffer is sent to SendCommand.
- v8::Isolate* isolate = CcTest::isolate();
- v8::Debug::SendCommand(isolate, buffer_1, AsciiToUtf16(command_1, buffer_1));
- v8::Debug::SendCommand(isolate, buffer_2, AsciiToUtf16(command_2, buffer_2));
- v8::Debug::SendCommand(isolate, buffer_2, AsciiToUtf16(command_3, buffer_2));
- v8::Debug::SendCommand(isolate, buffer_2, AsciiToUtf16(command_3, buffer_2));
- v8::Debug::SendCommand(isolate, buffer_2, AsciiToUtf16(command_3, buffer_2));
- message_queue_barriers.barrier_2.Wait();
- // Main thread compiles and runs source_2.
- // Queued commands are executed at the start of compilation of source_2(
- // beforeCompile event).
- // Free the message handler to process all the messages from the queue. 7
- // messages are expected: 2 afterCompile events and 5 responses.
- // All the commands added so far will fail to execute as long as call stack
- // is empty on beforeCompile event.
- for (int i = 0; i < 6 ; ++i) {
- message_queue_barriers.semaphore_1.Signal();
- }
- message_queue_barriers.barrier_3.Wait();
- // Main thread compiles and runs source_3.
- // Don't stop in the afterCompile handler.
- message_queue_barriers.semaphore_1.Signal();
- // source_3 includes a debugger statement, which causes a break event.
- // Wait on break event from hitting "debugger" statement
- message_queue_barriers.semaphore_2.Wait();
- // These should execute after the "debugger" statement in source_2
- v8::Debug::SendCommand(isolate, buffer_1, AsciiToUtf16(command_1, buffer_1));
- v8::Debug::SendCommand(isolate, buffer_2, AsciiToUtf16(command_2, buffer_2));
- v8::Debug::SendCommand(isolate, buffer_2, AsciiToUtf16(command_3, buffer_2));
- v8::Debug::SendCommand(
- isolate, buffer_2, AsciiToUtf16(command_single_step, buffer_2));
- // Run after 2 break events, 4 responses.
- for (int i = 0; i < 6 ; ++i) {
- message_queue_barriers.semaphore_1.Signal();
- }
- // Wait on break event after a single step executes.
- message_queue_barriers.semaphore_2.Wait();
- v8::Debug::SendCommand(isolate, buffer_1, AsciiToUtf16(command_2, buffer_1));
- v8::Debug::SendCommand(
- isolate, buffer_2, AsciiToUtf16(command_continue, buffer_2));
- // Run after 2 responses.
- for (int i = 0; i < 2 ; ++i) {
- message_queue_barriers.semaphore_1.Signal();
- }
- // Main thread continues running source_3 to end, waits for this thread.
-}
-
-
-// This thread runs the v8 engine.
-TEST(MessageQueues) {
- MessageQueueDebuggerThread message_queue_debugger_thread;
-
- // Create a V8 environment
- DebugLocalContext env;
- v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetMessageHandler(env->GetIsolate(), MessageHandler);
- message_queue_debugger_thread.Start();
-
- const char* source_1 = "a = 3; b = 4; c = new Object(); c.d = 5;";
- const char* source_2 = "e = 17;";
- const char* source_3 = "a = 4; debugger; a = 5; a = 6; a = 7;";
-
- // See MessageQueueDebuggerThread::Run for interleaved sequence of
- // API calls and events in the two threads.
- CompileRun(source_1);
- message_queue_barriers.barrier_1.Wait();
- message_queue_barriers.barrier_2.Wait();
- CompileRun(source_2);
- message_queue_barriers.barrier_3.Wait();
- CompileRun(source_3);
- message_queue_debugger_thread.Join();
- fflush(stdout);
-}
-
-
-class TestClientData : public v8::Debug::ClientData {
- public:
- TestClientData() {
- constructor_call_counter++;
- }
- virtual ~TestClientData() {
- destructor_call_counter++;
- }
-
- static void ResetCounters() {
- constructor_call_counter = 0;
- destructor_call_counter = 0;
- }
-
- static int constructor_call_counter;
- static int destructor_call_counter;
-};
-
-int TestClientData::constructor_call_counter = 0;
-int TestClientData::destructor_call_counter = 0;
-
-
-// Tests that MessageQueue doesn't destroy client data when expands and
-// does destroy when it dies.
-TEST(MessageQueueExpandAndDestroy) {
- TestClientData::ResetCounters();
- { // Create a scope for the queue.
- CommandMessageQueue queue(1);
- queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
- new TestClientData()));
- queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
- new TestClientData()));
- queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
- new TestClientData()));
- CHECK_EQ(0, TestClientData::destructor_call_counter);
- queue.Get().Dispose();
- CHECK_EQ(1, TestClientData::destructor_call_counter);
- queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
- new TestClientData()));
- queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
- new TestClientData()));
- queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
- new TestClientData()));
- queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
- new TestClientData()));
- queue.Put(CommandMessage::New(Vector<uint16_t>::empty(),
- new TestClientData()));
- CHECK_EQ(1, TestClientData::destructor_call_counter);
- queue.Get().Dispose();
- CHECK_EQ(2, TestClientData::destructor_call_counter);
- }
- // All the client data should be destroyed when the queue is destroyed.
- CHECK_EQ(TestClientData::destructor_call_counter,
- TestClientData::destructor_call_counter);
-}
-
-
-static int handled_client_data_instances_count = 0;
-static void MessageHandlerCountingClientData(
- const v8::Debug::Message& message) {
- if (message.GetClientData() != NULL) {
- handled_client_data_instances_count++;
- }
-}
-
-
-// Tests that all client data passed to the debugger are sent to the handler.
-TEST(SendClientDataToHandler) {
- // Create a V8 environment
- DebugLocalContext env;
- v8::Isolate* isolate = env->GetIsolate();
- v8::HandleScope scope(isolate);
- TestClientData::ResetCounters();
- handled_client_data_instances_count = 0;
- v8::Debug::SetMessageHandler(isolate, MessageHandlerCountingClientData);
- const char* source_1 = "a = 3; b = 4; c = new Object(); c.d = 5;";
- const int kBufferSize = 1000;
- uint16_t buffer[kBufferSize];
- const char* command_1 =
- "{\"seq\":117,"
- "\"type\":\"request\","
- "\"command\":\"evaluate\","
- "\"arguments\":{\"expression\":\"1+2\"}}";
- const char* command_2 =
- "{\"seq\":118,"
- "\"type\":\"request\","
- "\"command\":\"evaluate\","
- "\"arguments\":{\"expression\":\"1+a\"}}";
- const char* command_continue =
- "{\"seq\":106,"
- "\"type\":\"request\","
- "\"command\":\"continue\"}";
-
- v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_1, buffer),
- new TestClientData());
- v8::Debug::SendCommand(
- isolate, buffer, AsciiToUtf16(command_2, buffer), NULL);
- v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_2, buffer),
- new TestClientData());
- v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_2, buffer),
- new TestClientData());
- // All the messages will be processed on beforeCompile event.
- CompileRun(source_1);
- v8::Debug::SendCommand(
- isolate, buffer, AsciiToUtf16(command_continue, buffer));
- CHECK_EQ(3, TestClientData::constructor_call_counter);
- CHECK_EQ(TestClientData::constructor_call_counter,
- handled_client_data_instances_count);
- CHECK_EQ(TestClientData::constructor_call_counter,
- TestClientData::destructor_call_counter);
-}
-
-
-/* Test ThreadedDebugging */
-/* This test interrupts a running infinite loop that is
- * occupying the v8 thread by a break command from the
- * debugger thread. It then changes the value of a
- * global object, to make the loop terminate.
- */
-
-Barriers threaded_debugging_barriers;
-
-class V8Thread : public v8::base::Thread {
- public:
- V8Thread() : Thread(Options("V8Thread")) {}
- void Run();
- v8::Isolate* isolate() { return isolate_; }
-
- private:
- v8::Isolate* isolate_;
-};
-
-class DebuggerThread : public v8::base::Thread {
- public:
- explicit DebuggerThread(v8::Isolate* isolate)
- : Thread(Options("DebuggerThread")), isolate_(isolate) {}
- void Run();
-
- private:
- v8::Isolate* isolate_;
-};
-
-
-static void ThreadedAtBarrier1(
- const v8::FunctionCallbackInfo<v8::Value>& args) {
- threaded_debugging_barriers.barrier_1.Wait();
-}
-
-
-static void ThreadedMessageHandler(const v8::Debug::Message& message) {
- static char print_buffer[1000];
- v8::String::Value json(message.GetJSON());
- Utf16ToAscii(*json, json.length(), print_buffer);
- if (IsBreakEventMessage(print_buffer)) {
- // Check that we are inside the while loop.
- int source_line = GetSourceLineFromBreakEventMessage(print_buffer);
- CHECK(4 <= source_line && source_line <= 10);
- threaded_debugging_barriers.barrier_2.Wait();
- }
-}
-
-
-void V8Thread::Run() {
- const char* source =
- "flag = true;\n"
- "\n"
- "function foo() {\n"
- " var x = 1;\n"
- " while ( flag == true ) {\n"
- " if ( x == 1 ) {\n"
- " ThreadedAtBarrier1();\n"
- " }\n"
- " x = x + 1;\n"
- " }\n"
- "}\n"
- "\n"
- "foo();\n";
-
- v8::Isolate::CreateParams create_params;
- create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
- isolate_ = v8::Isolate::New(create_params);
- threaded_debugging_barriers.barrier_3.Wait();
- {
- v8::Isolate::Scope isolate_scope(isolate_);
- DebugLocalContext env(isolate_);
- v8::HandleScope scope(isolate_);
- v8::Debug::SetMessageHandler(isolate_, &ThreadedMessageHandler);
- v8::Local<v8::ObjectTemplate> global_template =
- v8::ObjectTemplate::New(env->GetIsolate());
- global_template->Set(
- v8_str(env->GetIsolate(), "ThreadedAtBarrier1"),
- v8::FunctionTemplate::New(isolate_, ThreadedAtBarrier1));
- v8::Local<v8::Context> context =
- v8::Context::New(isolate_, NULL, global_template);
- v8::Context::Scope context_scope(context);
-
- CompileRun(source);
- }
- threaded_debugging_barriers.barrier_4.Wait();
- isolate_->Dispose();
-}
-
-
-void DebuggerThread::Run() {
- const int kBufSize = 1000;
- uint16_t buffer[kBufSize];
-
- const char* command_1 =
- "{\"seq\":102,"
- "\"type\":\"request\","
- "\"command\":\"evaluate\","
- "\"arguments\":{\"expression\":\"flag = false\"}}";
- const char* command_2 = "{\"seq\":103,"
- "\"type\":\"request\","
- "\"command\":\"continue\"}";
-
- threaded_debugging_barriers.barrier_1.Wait();
- v8::Debug::DebugBreak(isolate_);
- threaded_debugging_barriers.barrier_2.Wait();
- v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_1, buffer));
- v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_2, buffer));
- threaded_debugging_barriers.barrier_4.Wait();
-}
-
-
-TEST(ThreadedDebugging) {
- V8Thread v8_thread;
-
- // Create a V8 environment
- v8_thread.Start();
- threaded_debugging_barriers.barrier_3.Wait();
- DebuggerThread debugger_thread(v8_thread.isolate());
- debugger_thread.Start();
-
- v8_thread.Join();
- debugger_thread.Join();
-}
-
-
-/* Test RecursiveBreakpoints */
-/* In this test, the debugger evaluates a function with a breakpoint, after
- * hitting a breakpoint in another function. We do this with both values
- * of the flag enabling recursive breakpoints, and verify that the second
- * breakpoint is hit when enabled, and missed when disabled.
- */
-
-class BreakpointsV8Thread : public v8::base::Thread {
- public:
- BreakpointsV8Thread() : Thread(Options("BreakpointsV8Thread")) {}
- void Run();
-
- v8::Isolate* isolate() { return isolate_; }
-
- private:
- v8::Isolate* isolate_;
-};
-
-class BreakpointsDebuggerThread : public v8::base::Thread {
- public:
- BreakpointsDebuggerThread(bool global_evaluate, v8::Isolate* isolate)
- : Thread(Options("BreakpointsDebuggerThread")),
- global_evaluate_(global_evaluate),
- isolate_(isolate) {}
- void Run();
-
- private:
- bool global_evaluate_;
- v8::Isolate* isolate_;
-};
-
-
-Barriers* breakpoints_barriers;
-int break_event_breakpoint_id;
-int evaluate_int_result;
-
-static void BreakpointsMessageHandler(const v8::Debug::Message& message) {
- static char print_buffer[1000];
- v8::String::Value json(message.GetJSON());
- Utf16ToAscii(*json, json.length(), print_buffer);
-
- if (IsBreakEventMessage(print_buffer)) {
- break_event_breakpoint_id =
- GetBreakpointIdFromBreakEventMessage(print_buffer);
- breakpoints_barriers->semaphore_1.Signal();
- } else if (IsEvaluateResponseMessage(print_buffer)) {
- evaluate_int_result = GetEvaluateIntResult(print_buffer);
- breakpoints_barriers->semaphore_1.Signal();
- }
-}
-
-
-void BreakpointsV8Thread::Run() {
- const char* source_1 = "var y_global = 3;\n"
- "function cat( new_value ) {\n"
- " var x = new_value;\n"
- " y_global = y_global + 4;\n"
- " x = 3 * x + 1;\n"
- " y_global = y_global + 5;\n"
- " return x;\n"
- "}\n"
- "\n"
- "function dog() {\n"
- " var x = 1;\n"
- " x = y_global;"
- " var z = 3;"
- " x += 100;\n"
- " return x;\n"
- "}\n"
- "\n";
- const char* source_2 = "cat(17);\n"
- "cat(19);\n";
-
- v8::Isolate::CreateParams create_params;
- create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
- isolate_ = v8::Isolate::New(create_params);
- breakpoints_barriers->barrier_3.Wait();
- {
- v8::Isolate::Scope isolate_scope(isolate_);
- DebugLocalContext env(isolate_);
- v8::HandleScope scope(isolate_);
- v8::Debug::SetMessageHandler(isolate_, &BreakpointsMessageHandler);
-
- CompileRun(source_1);
- breakpoints_barriers->barrier_1.Wait();
- breakpoints_barriers->barrier_2.Wait();
- CompileRun(source_2);
- }
- breakpoints_barriers->barrier_4.Wait();
- isolate_->Dispose();
-}
-
-
-void BreakpointsDebuggerThread::Run() {
- const int kBufSize = 1000;
- uint16_t buffer[kBufSize];
-
- const char* command_1 = "{\"seq\":101,"
- "\"type\":\"request\","
- "\"command\":\"setbreakpoint\","
- "\"arguments\":{\"type\":\"function\",\"target\":\"cat\",\"line\":3}}";
- const char* command_2 = "{\"seq\":102,"
- "\"type\":\"request\","
- "\"command\":\"setbreakpoint\","
- "\"arguments\":{\"type\":\"function\",\"target\":\"dog\",\"line\":3}}";
- const char* command_3;
- if (this->global_evaluate_) {
- command_3 = "{\"seq\":103,"
- "\"type\":\"request\","
- "\"command\":\"evaluate\","
- "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":false,"
- "\"global\":true}}";
- } else {
- command_3 = "{\"seq\":103,"
- "\"type\":\"request\","
- "\"command\":\"evaluate\","
- "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":false}}";
- }
- const char* command_4;
- if (this->global_evaluate_) {
- command_4 = "{\"seq\":104,"
- "\"type\":\"request\","
- "\"command\":\"evaluate\","
- "\"arguments\":{\"expression\":\"100 + 8\",\"disable_break\":true,"
- "\"global\":true}}";
- } else {
- command_4 = "{\"seq\":104,"
- "\"type\":\"request\","
- "\"command\":\"evaluate\","
- "\"arguments\":{\"expression\":\"x + 1\",\"disable_break\":true}}";
- }
- const char* command_5 = "{\"seq\":105,"
- "\"type\":\"request\","
- "\"command\":\"continue\"}";
- const char* command_6 = "{\"seq\":106,"
- "\"type\":\"request\","
- "\"command\":\"continue\"}";
- const char* command_7;
- if (this->global_evaluate_) {
- command_7 = "{\"seq\":107,"
- "\"type\":\"request\","
- "\"command\":\"evaluate\","
- "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":true,"
- "\"global\":true}}";
- } else {
- command_7 = "{\"seq\":107,"
- "\"type\":\"request\","
- "\"command\":\"evaluate\","
- "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":true}}";
- }
- const char* command_8 = "{\"seq\":108,"
- "\"type\":\"request\","
- "\"command\":\"continue\"}";
-
-
- // v8 thread initializes, runs source_1
- breakpoints_barriers->barrier_1.Wait();
- // 1:Set breakpoint in cat() (will get id 1).
- v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_1, buffer));
- // 2:Set breakpoint in dog() (will get id 2).
- v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_2, buffer));
- breakpoints_barriers->barrier_2.Wait();
- // V8 thread starts compiling source_2.
- // Automatic break happens, to run queued commands
- // breakpoints_barriers->semaphore_1.Wait();
- // Commands 1 through 3 run, thread continues.
- // v8 thread runs source_2 to breakpoint in cat().
- // message callback receives break event.
- breakpoints_barriers->semaphore_1.Wait();
- // Must have hit breakpoint #1.
- CHECK_EQ(1, break_event_breakpoint_id);
- // 4:Evaluate dog() (which has a breakpoint).
- v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_3, buffer));
- // V8 thread hits breakpoint in dog().
- breakpoints_barriers->semaphore_1.Wait(); // wait for break event
- // Must have hit breakpoint #2.
- CHECK_EQ(2, break_event_breakpoint_id);
- // 5:Evaluate (x + 1).
- v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_4, buffer));
- // Evaluate (x + 1) finishes.
- breakpoints_barriers->semaphore_1.Wait();
- // Must have result 108.
- CHECK_EQ(108, evaluate_int_result);
- // 6:Continue evaluation of dog().
- v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_5, buffer));
- // Evaluate dog() finishes.
- breakpoints_barriers->semaphore_1.Wait();
- // Must have result 107.
- CHECK_EQ(107, evaluate_int_result);
- // 7:Continue evaluation of source_2, finish cat(17), hit breakpoint
- // in cat(19).
- v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_6, buffer));
- // Message callback gets break event.
- breakpoints_barriers->semaphore_1.Wait(); // wait for break event
- // Must have hit breakpoint #1.
- CHECK_EQ(1, break_event_breakpoint_id);
- // 8: Evaluate dog() with breaks disabled.
- v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_7, buffer));
- // Evaluate dog() finishes.
- breakpoints_barriers->semaphore_1.Wait();
- // Must have result 116.
- CHECK_EQ(116, evaluate_int_result);
- // 9: Continue evaluation of source2, reach end.
- v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_8, buffer));
- breakpoints_barriers->barrier_4.Wait();
-}
-
-
-void TestRecursiveBreakpointsGeneric(bool global_evaluate) {
- BreakpointsV8Thread breakpoints_v8_thread;
-
- // Create a V8 environment
- Barriers stack_allocated_breakpoints_barriers;
- breakpoints_barriers = &stack_allocated_breakpoints_barriers;
-
- breakpoints_v8_thread.Start();
- breakpoints_barriers->barrier_3.Wait();
- BreakpointsDebuggerThread breakpoints_debugger_thread(
- global_evaluate, breakpoints_v8_thread.isolate());
- breakpoints_debugger_thread.Start();
-
- breakpoints_v8_thread.Join();
- breakpoints_debugger_thread.Join();
-}
-
-
-TEST(RecursiveBreakpoints) {
- TestRecursiveBreakpointsGeneric(false);
-}
-
-
-TEST(RecursiveBreakpointsGlobal) {
- TestRecursiveBreakpointsGeneric(true);
-}
-
-
TEST(SetDebugEventListenerOnUninitializedVM) {
v8::Debug::SetDebugEventListener(CcTest::isolate(), DummyDebugEventListener);
}
-
-static void DummyMessageHandler(const v8::Debug::Message& message) {
-}
-
-
-TEST(SetMessageHandlerOnUninitializedVM) {
- v8::Debug::SetMessageHandler(CcTest::isolate(), DummyMessageHandler);
-}
-
-
// Source for a JavaScript function which returns the data parameter of a
// function called in the context of the debugger. If no data parameter is
// passed it throws an exception.
@@ -5931,19 +4838,6 @@ TEST(CallFunctionInDebugger) {
}
-// Debugger message handler which counts the number of breaks.
-static void SendContinueCommand();
-static void MessageHandlerBreakPointHitCount(
- const v8::Debug::Message& message) {
- if (message.IsEvent() && message.GetEvent() == v8::Break) {
- // Count the number of breaks.
- break_point_hit_count++;
-
- SendContinueCommand();
- }
-}
-
-
// Test that clearing the debug event listener actually clears all break points
// and related information.
TEST(DebuggerUnload) {
@@ -5983,132 +4877,41 @@ TEST(DebuggerUnload) {
// outside a handle scope.
v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr);
CheckDebuggerUnloaded(env->GetIsolate(), true);
-
- // Now set a debug message handler.
- break_point_hit_count = 0;
- v8::Debug::SetMessageHandler(env->GetIsolate(),
- MessageHandlerBreakPointHitCount);
- {
- v8::HandleScope scope(env->GetIsolate());
-
- // Get the test functions again.
- v8::Local<v8::Function> foo(v8::Local<v8::Function>::Cast(
- env->Global()
- ->Get(context, v8_str(env->GetIsolate(), "foo"))
- .ToLocalChecked()));
-
- foo->Call(context, env->Global(), 0, NULL).ToLocalChecked();
- CHECK_EQ(0, break_point_hit_count);
-
- // Set break points and run again.
- SetBreakPoint(foo, 0);
- SetBreakPoint(foo, 4);
- foo->Call(context, env->Global(), 0, NULL).ToLocalChecked();
- CHECK_EQ(2, break_point_hit_count);
- }
-
- // Remove the debug message handler without clearing breakpoints. Do this
- // outside a handle scope.
- v8::Debug::SetMessageHandler(env->GetIsolate(), nullptr);
- CheckDebuggerUnloaded(env->GetIsolate(), true);
}
+int event_listener_hit_count = 0;
-// Sends continue command to the debugger.
-static void SendContinueCommand() {
- const int kBufferSize = 1000;
- uint16_t buffer[kBufferSize];
- const char* command_continue =
- "{\"seq\":0,"
- "\"type\":\"request\","
- "\"command\":\"continue\"}";
+// Debugger event listener which clears itself while active.
+static void EventListenerClearingItself(
+ const v8::Debug::EventDetails& details) {
+ event_listener_hit_count++;
- v8::Debug::SendCommand(
- CcTest::isolate(), buffer, AsciiToUtf16(command_continue, buffer));
-}
-
-
-// Debugger message handler which counts the number of times it is called.
-static int message_handler_hit_count = 0;
-static void MessageHandlerHitCount(const v8::Debug::Message& message) {
- message_handler_hit_count++;
-
- static char print_buffer[1000];
- v8::String::Value json(message.GetJSON());
- Utf16ToAscii(*json, json.length(), print_buffer);
- if (IsExceptionEventMessage(print_buffer)) {
- // Send a continue command for exception events.
- SendContinueCommand();
- }
-}
-
-
-// Test clearing the debug message handler.
-TEST(DebuggerClearMessageHandler) {
- DebugLocalContext env;
- v8::HandleScope scope(env->GetIsolate());
-
- // Check debugger is unloaded before it is used.
- CheckDebuggerUnloaded(env->GetIsolate());
-
- // Set a debug message handler.
- v8::Debug::SetMessageHandler(env->GetIsolate(), MessageHandlerHitCount);
-
- // Run code to throw a unhandled exception. This should end up in the message
- // handler.
- CompileRun("throw 1");
-
- // The message handler should be called.
- CHECK_GT(message_handler_hit_count, 0);
-
- // Clear debug message handler.
- message_handler_hit_count = 0;
- v8::Debug::SetMessageHandler(env->GetIsolate(), nullptr);
-
- // Run code to throw a unhandled exception. This should end up in the message
- // handler.
- CompileRun("throw 1");
-
- // The message handler should not be called more.
- CHECK_EQ(0, message_handler_hit_count);
-
- CheckDebuggerUnloaded(env->GetIsolate(), true);
-}
-
-
-// Debugger message handler which clears the message handler while active.
-static void MessageHandlerClearingMessageHandler(
- const v8::Debug::Message& message) {
- message_handler_hit_count++;
-
- // Clear debug message handler.
- v8::Debug::SetMessageHandler(message.GetIsolate(), nullptr);
+ // Clear debug event listener.
+ v8::Debug::SetDebugEventListener(details.GetIsolate(), nullptr);
}
// Test clearing the debug message handler while processing a debug event.
-TEST(DebuggerClearMessageHandlerWhileActive) {
+TEST(DebuggerClearEventListenerWhileActive) {
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
// Check debugger is unloaded before it is used.
CheckDebuggerUnloaded(env->GetIsolate());
- // Set a debug message handler.
- v8::Debug::SetMessageHandler(env->GetIsolate(),
- MessageHandlerClearingMessageHandler);
+ // Set a debug event listener.
+ v8::Debug::SetDebugEventListener(env->GetIsolate(),
+ EventListenerClearingItself);
- // Run code to throw a unhandled exception. This should end up in the message
- // handler.
+ // Run code to throw an uncaught exception. This should trigger the listener.
CompileRun("throw 1");
- // The message handler should be called.
- CHECK_EQ(1, message_handler_hit_count);
+ // The event listener should have been called.
+ CHECK_EQ(1, event_listener_hit_count);
CheckDebuggerUnloaded(env->GetIsolate(), true);
}
-
// Test for issue http://code.google.com/p/v8/issues/detail?id=289.
// Make sure that DebugGetLoadedScripts doesn't return scripts
// with disposed external source.
@@ -6258,26 +5061,18 @@ static v8::Local<v8::Value> expected_context_data;
// Check that the expected context is the one generating the debug event.
-static void ContextCheckMessageHandler(const v8::Debug::Message& message) {
- CHECK(message.GetEventContext() == expected_context);
- CHECK(message.GetEventContext()->GetEmbedderData(0)->StrictEquals(
+static void ContextCheckEventListener(
+ const v8::Debug::EventDetails& event_details) {
+ CHECK(event_details.GetEventContext() == expected_context);
+ CHECK(event_details.GetEventContext()->GetEmbedderData(0)->StrictEquals(
expected_context_data));
- message_handler_hit_count++;
-
- static char print_buffer[1000];
- v8::String::Value json(message.GetJSON());
- Utf16ToAscii(*json, json.length(), print_buffer);
-
- // Send a continue command for break events.
- if (IsBreakEventMessage(print_buffer)) {
- SendContinueCommand();
- }
+ event_listener_hit_count++;
}
// Test which creates two contexts and sets different embedder data on each.
-// Checks that this data is set correctly and that when the debug message
-// handler is called the expected context is the one active.
+// Checks that this data is set correctly and that when the debug event
+// listener is called the expected context is the one active.
TEST(ContextData) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
@@ -6291,7 +5086,7 @@ TEST(ContextData) {
context_1 = v8::Context::New(isolate, NULL, global_template, global_object);
context_2 = v8::Context::New(isolate, NULL, global_template, global_object);
- v8::Debug::SetMessageHandler(isolate, ContextCheckMessageHandler);
+ v8::Debug::SetDebugEventListener(isolate, ContextCheckEventListener);
// Default data value is undefined.
CHECK(context_1->GetEmbedderData(0)->IsUndefined());
@@ -6328,39 +5123,31 @@ TEST(ContextData) {
}
// Two times compile event and two times break event.
- CHECK_GT(message_handler_hit_count, 4);
+ CHECK_GT(event_listener_hit_count, 3);
- v8::Debug::SetMessageHandler(isolate, nullptr);
+ v8::Debug::SetDebugEventListener(isolate, nullptr);
CheckDebuggerUnloaded(isolate);
}
-
-// Debug message handler which issues a debug break when it hits a break event.
-static int message_handler_break_hit_count = 0;
-static void DebugBreakMessageHandler(const v8::Debug::Message& message) {
+// Debug event listener which issues a debug break when it hits a break event.
+static int event_listener_break_hit_count = 0;
+static void DebugBreakEventListener(const v8::Debug::EventDetails& details) {
// Schedule a debug break for break events.
- if (message.IsEvent() && message.GetEvent() == v8::Break) {
- message_handler_break_hit_count++;
- if (message_handler_break_hit_count == 1) {
- v8::Debug::DebugBreak(message.GetIsolate());
+ if (details.GetEvent() == v8::Break) {
+ event_listener_break_hit_count++;
+ if (event_listener_break_hit_count == 1) {
+ v8::Debug::DebugBreak(details.GetIsolate());
}
}
-
- // Issue a continue command if this event will not cause the VM to start
- // running.
- if (!message.WillStartRunning()) {
- SendContinueCommand();
- }
}
-
-// Test that a debug break can be scheduled while in a message handler.
-TEST(DebugBreakInMessageHandler) {
+// Test that a debug break can be scheduled while in a event listener.
+TEST(DebugBreakInEventListener) {
i::FLAG_turbo_inlining = false; // Make sure g is not inlined into f.
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetMessageHandler(env->GetIsolate(), DebugBreakMessageHandler);
+ v8::Debug::SetDebugEventListener(env->GetIsolate(), DebugBreakEventListener);
v8::Local<v8::Context> context = env.context();
// Test functions.
@@ -6378,10 +5165,10 @@ TEST(DebugBreakInMessageHandler) {
// Call f then g. The debugger statement in f will cause a break which will
// cause another break.
f->Call(context, env->Global(), 0, NULL).ToLocalChecked();
- CHECK_EQ(2, message_handler_break_hit_count);
+ CHECK_EQ(2, event_listener_break_hit_count);
// Calling g will not cause any additional breaks.
g->Call(context, env->Global(), 0, NULL).ToLocalChecked();
- CHECK_EQ(2, message_handler_break_hit_count);
+ CHECK_EQ(2, event_listener_break_hit_count);
}
@@ -6458,18 +5245,21 @@ TEST(RegExpDebugBreak) {
}
#endif // V8_INTERPRETED_REGEXP
+// Test which creates a context and sets embedder data on it. Checks that this
+// data is set correctly and that when the debug event listener is called for
+// break event in an eval statement the expected context is the one returned by
+// Message.GetEventContext.
+TEST(EvalContextData) {
+ v8::HandleScope scope(CcTest::isolate());
-// Common part of EvalContextData and NestedBreakEventContextData tests.
-static void ExecuteScriptForContextCheck(
- v8::Debug::MessageHandler message_handler) {
- // Create a context.
v8::Local<v8::Context> context_1;
v8::Local<v8::ObjectTemplate> global_template =
v8::Local<v8::ObjectTemplate>();
context_1 =
v8::Context::New(CcTest::isolate(), NULL, global_template);
- v8::Debug::SetMessageHandler(CcTest::isolate(), message_handler);
+ v8::Debug::SetDebugEventListener(CcTest::isolate(),
+ ContextCheckEventListener);
// Default data value is undefined.
CHECK(context_1->GetEmbedderData(0)->IsUndefined());
@@ -6491,124 +5281,42 @@ static void ExecuteScriptForContextCheck(
f->Call(context_1, context_1->Global(), 0, NULL).ToLocalChecked();
}
- v8::Debug::SetMessageHandler(CcTest::isolate(), nullptr);
-}
-
-
-// Test which creates a context and sets embedder data on it. Checks that this
-// data is set correctly and that when the debug message handler is called for
-// break event in an eval statement the expected context is the one returned by
-// Message.GetEventContext.
-TEST(EvalContextData) {
- v8::HandleScope scope(CcTest::isolate());
-
- ExecuteScriptForContextCheck(ContextCheckMessageHandler);
+ v8::Debug::SetDebugEventListener(CcTest::isolate(), nullptr);
// One time compile event and one time break event.
- CHECK_GT(message_handler_hit_count, 2);
- CheckDebuggerUnloaded(CcTest::isolate());
-}
-
-
-static bool sent_eval = false;
-static int break_count = 0;
-static int continue_command_send_count = 0;
-// Check that the expected context is the one generating the debug event
-// including the case of nested break event.
-static void DebugEvalContextCheckMessageHandler(
- const v8::Debug::Message& message) {
- CHECK(message.GetEventContext() == expected_context);
- CHECK(message.GetEventContext()->GetEmbedderData(0)->StrictEquals(
- expected_context_data));
- message_handler_hit_count++;
-
- static char print_buffer[1000];
- v8::String::Value json(message.GetJSON());
- Utf16ToAscii(*json, json.length(), print_buffer);
-
- v8::Isolate* isolate = message.GetIsolate();
- if (IsBreakEventMessage(print_buffer)) {
- break_count++;
- if (!sent_eval) {
- sent_eval = true;
-
- const int kBufferSize = 1000;
- uint16_t buffer[kBufferSize];
- const char* eval_command =
- "{\"seq\":0,"
- "\"type\":\"request\","
- "\"command\":\"evaluate\","
- "\"arguments\":{\"expression\":\"debugger;\","
- "\"global\":true,\"disable_break\":false}}";
-
- // Send evaluate command.
- v8::Debug::SendCommand(
- isolate, buffer, AsciiToUtf16(eval_command, buffer));
- return;
- } else {
- // It's a break event caused by the evaluation request above.
- SendContinueCommand();
- continue_command_send_count++;
- }
- } else if (IsEvaluateResponseMessage(print_buffer) &&
- continue_command_send_count < 2) {
- // Response to the evaluation request. We're still on the breakpoint so
- // send continue.
- SendContinueCommand();
- continue_command_send_count++;
- }
-}
-
-
-// Tests that context returned for break event is correct when the event occurs
-// in 'evaluate' debugger request.
-TEST(NestedBreakEventContextData) {
- v8::HandleScope scope(CcTest::isolate());
- break_count = 0;
- message_handler_hit_count = 0;
-
- ExecuteScriptForContextCheck(DebugEvalContextCheckMessageHandler);
-
- // One time compile event and two times break event.
- CHECK_GT(message_handler_hit_count, 3);
-
- // One break from the source and another from the evaluate request.
- CHECK_EQ(break_count, 2);
+ CHECK_GT(event_listener_hit_count, 2);
CheckDebuggerUnloaded(CcTest::isolate());
}
// Debug event listener which counts the after compile events.
-int after_compile_message_count = 0;
-static void AfterCompileMessageHandler(const v8::Debug::Message& message) {
+int after_compile_event_count = 0;
+static void AfterCompileEventListener(const v8::Debug::EventDetails& details) {
// Count the number of scripts collected.
- if (message.IsEvent()) {
- if (message.GetEvent() == v8::AfterCompile) {
- after_compile_message_count++;
- } else if (message.GetEvent() == v8::Break) {
- SendContinueCommand();
- }
+ if (details.GetEvent() == v8::AfterCompile) {
+ after_compile_event_count++;
}
}
// Tests that after compile event is sent as many times as there are scripts
// compiled.
-TEST(AfterCompileMessageWhenMessageHandlerIsReset) {
+TEST(AfterCompileEventWhenEventListenerIsReset) {
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
v8::Local<v8::Context> context = env.context();
- after_compile_message_count = 0;
const char* script = "var a=1";
- v8::Debug::SetMessageHandler(env->GetIsolate(), AfterCompileMessageHandler);
+ v8::Debug::SetDebugEventListener(env->GetIsolate(),
+ AfterCompileEventListener);
v8::Script::Compile(context, v8_str(env->GetIsolate(), script))
.ToLocalChecked()
->Run(context)
.ToLocalChecked();
- v8::Debug::SetMessageHandler(env->GetIsolate(), nullptr);
+ v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr);
- v8::Debug::SetMessageHandler(env->GetIsolate(), AfterCompileMessageHandler);
+ v8::Debug::SetDebugEventListener(env->GetIsolate(),
+ AfterCompileEventListener);
v8::Debug::DebugBreak(env->GetIsolate());
v8::Script::Compile(context, v8_str(env->GetIsolate(), script))
.ToLocalChecked()
@@ -6616,11 +5324,11 @@ TEST(AfterCompileMessageWhenMessageHandlerIsReset) {
.ToLocalChecked();
// Setting listener to NULL should cause debugger unload.
- v8::Debug::SetMessageHandler(env->GetIsolate(), nullptr);
+ v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr);
CheckDebuggerUnloaded(env->GetIsolate());
// Compilation cache should be disabled when debugger is active.
- CHECK_EQ(2, after_compile_message_count);
+ CHECK_EQ(2, after_compile_event_count);
}
@@ -6643,7 +5351,7 @@ static void CompileErrorEventCounter(
// Tests that syntax error event is sent as many times as there are scripts
// with syntax error compiled.
-TEST(SyntaxErrorMessageOnSyntaxException) {
+TEST(SyntaxErrorEventOnSyntaxException) {
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -6685,23 +5393,23 @@ TEST(SyntaxErrorMessageOnSyntaxException) {
CHECK_EQ(3, compile_error_event_count);
}
-
-// Tests that break event is sent when message handler is reset.
-TEST(BreakMessageWhenMessageHandlerIsReset) {
+// Tests that break event is sent when event listener is reset.
+TEST(BreakEventWhenEventListenerIsReset) {
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
v8::Local<v8::Context> context = env.context();
- after_compile_message_count = 0;
const char* script = "function f() {};";
- v8::Debug::SetMessageHandler(env->GetIsolate(), AfterCompileMessageHandler);
+ v8::Debug::SetDebugEventListener(env->GetIsolate(),
+ AfterCompileEventListener);
v8::Script::Compile(context, v8_str(env->GetIsolate(), script))
.ToLocalChecked()
->Run(context)
.ToLocalChecked();
- v8::Debug::SetMessageHandler(env->GetIsolate(), nullptr);
+ v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr);
- v8::Debug::SetMessageHandler(env->GetIsolate(), AfterCompileMessageHandler);
+ v8::Debug::SetDebugEventListener(env->GetIsolate(),
+ AfterCompileEventListener);
v8::Debug::DebugBreak(env->GetIsolate());
v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
env->Global()
@@ -6709,26 +5417,22 @@ TEST(BreakMessageWhenMessageHandlerIsReset) {
.ToLocalChecked());
f->Call(context, env->Global(), 0, NULL).ToLocalChecked();
- // Setting message handler to NULL should cause debugger unload.
- v8::Debug::SetMessageHandler(env->GetIsolate(), nullptr);
+ // Setting event listener to NULL should cause debugger unload.
+ v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr);
CheckDebuggerUnloaded(env->GetIsolate());
// Compilation cache should be disabled when debugger is active.
- CHECK_EQ(1, after_compile_message_count);
+ CHECK_EQ(1, after_compile_event_count);
}
static int exception_event_count = 0;
-static void ExceptionMessageHandler(const v8::Debug::Message& message) {
- if (message.IsEvent() && message.GetEvent() == v8::Exception) {
- exception_event_count++;
- SendContinueCommand();
- }
+static void ExceptionEventListener(const v8::Debug::EventDetails& details) {
+ if (details.GetEvent() == v8::Exception) exception_event_count++;
}
-
-// Tests that exception event is sent when message handler is reset.
-TEST(ExceptionMessageWhenMessageHandlerIsReset) {
+// Tests that exception event is sent when event listener is reset.
+TEST(ExceptionEventWhenEventListenerIsReset) {
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -6739,22 +5443,23 @@ TEST(ExceptionMessageWhenMessageHandlerIsReset) {
exception_event_count = 0;
const char* script = "function f() {throw new Error()};";
- v8::Debug::SetMessageHandler(env->GetIsolate(), AfterCompileMessageHandler);
+ v8::Debug::SetDebugEventListener(env->GetIsolate(),
+ AfterCompileEventListener);
v8::Script::Compile(context, v8_str(env->GetIsolate(), script))
.ToLocalChecked()
->Run(context)
.ToLocalChecked();
- v8::Debug::SetMessageHandler(env->GetIsolate(), nullptr);
+ v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr);
- v8::Debug::SetMessageHandler(env->GetIsolate(), ExceptionMessageHandler);
+ v8::Debug::SetDebugEventListener(env->GetIsolate(), ExceptionEventListener);
v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
env->Global()
->Get(context, v8_str(env->GetIsolate(), "f"))
.ToLocalChecked());
CHECK(f->Call(context, env->Global(), 0, NULL).IsEmpty());
- // Setting message handler to NULL should cause debugger unload.
- v8::Debug::SetMessageHandler(env->GetIsolate(), nullptr);
+ // Setting event listener to NULL should cause debugger unload.
+ v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr);
CheckDebuggerUnloaded(env->GetIsolate());
CHECK_EQ(1, exception_event_count);
@@ -6770,7 +5475,8 @@ TEST(ProvisionalBreakpointOnLineOutOfRange) {
const char* script = "function f() {};";
const char* resource_name = "test_resource";
- v8::Debug::SetMessageHandler(env->GetIsolate(), AfterCompileMessageHandler);
+ v8::Debug::SetDebugEventListener(env->GetIsolate(),
+ AfterCompileEventListener);
v8::Local<v8::Context> context = env.context();
// Set a couple of provisional breakpoint on lines out of the script lines
@@ -6780,7 +5486,7 @@ TEST(ProvisionalBreakpointOnLineOutOfRange) {
int sbp2 =
SetScriptBreakPointByNameFromJS(env->GetIsolate(), resource_name, 5, 5);
- after_compile_message_count = 0;
+ after_compile_event_count = 0;
v8::ScriptOrigin origin(v8_str(env->GetIsolate(), resource_name),
v8::Integer::New(env->GetIsolate(), 10),
@@ -6795,46 +5501,28 @@ TEST(ProvisionalBreakpointOnLineOutOfRange) {
// If the script is compiled successfully there is exactly one after compile
// event. In case of an exception in debugger code after compile event is not
// sent.
- CHECK_EQ(1, after_compile_message_count);
+ CHECK_EQ(1, after_compile_event_count);
ClearBreakPointFromJS(env->GetIsolate(), sbp1);
ClearBreakPointFromJS(env->GetIsolate(), sbp2);
- v8::Debug::SetMessageHandler(env->GetIsolate(), nullptr);
+ v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr);
+ CheckDebuggerUnloaded(env->GetIsolate());
}
-
-static void BreakMessageHandler(const v8::Debug::Message& message) {
- i::Isolate* isolate = CcTest::i_isolate();
- if (message.IsEvent() && message.GetEvent() == v8::Break) {
- // Count the number of breaks.
- break_point_hit_count++;
-
- i::HandleScope scope(isolate);
- message.GetJSON();
-
- SendContinueCommand();
- } else if (message.IsEvent() && message.GetEvent() == v8::AfterCompile) {
- i::HandleScope scope(isolate);
-
- int current_count = break_point_hit_count;
-
- // Force serialization to trigger some internal JS execution.
- message.GetJSON();
-
- CHECK_EQ(current_count, break_point_hit_count);
- }
+static void BreakEventListener(const v8::Debug::EventDetails& details) {
+ if (details.GetEvent() == v8::Break) break_point_hit_count++;
}
// Test that if DebugBreak is forced it is ignored when code from
// debug-delay.js is executed.
-TEST(NoDebugBreakInAfterCompileMessageHandler) {
+TEST(NoDebugBreakInAfterCompileEventListener) {
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
v8::Local<v8::Context> context = env.context();
// Register a debug event listener which sets the break flag and counts.
- v8::Debug::SetMessageHandler(env->GetIsolate(), BreakMessageHandler);
+ v8::Debug::SetDebugEventListener(env->GetIsolate(), BreakEventListener);
// Set the debug break flag.
v8::Debug::DebugBreak(env->GetIsolate());
@@ -6852,237 +5540,12 @@ TEST(NoDebugBreakInAfterCompileMessageHandler) {
// There should be one more break event when the script is evaluated in 'f'.
CHECK_EQ(2, break_point_hit_count);
- // Get rid of the debug message handler.
- v8::Debug::SetMessageHandler(env->GetIsolate(), nullptr);
+ // Get rid of the debug event listener.
+ v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr);
CheckDebuggerUnloaded(env->GetIsolate());
}
-static int counting_message_handler_counter;
-
-static void CountingMessageHandler(const v8::Debug::Message& message) {
- if (message.IsResponse()) counting_message_handler_counter++;
-}
-
-
-// Test that debug messages get processed when ProcessDebugMessages is called.
-TEST(ProcessDebugMessages) {
- DebugLocalContext env;
- v8::Isolate* isolate = env->GetIsolate();
- v8::HandleScope scope(isolate);
-
- counting_message_handler_counter = 0;
-
- v8::Debug::SetMessageHandler(isolate, CountingMessageHandler);
-
- const int kBufferSize = 1000;
- uint16_t buffer[kBufferSize];
- const char* scripts_command =
- "{\"seq\":0,"
- "\"type\":\"request\","
- "\"command\":\"scripts\"}";
-
- // Send scripts command.
- v8::Debug::SendCommand(
- isolate, buffer, AsciiToUtf16(scripts_command, buffer));
-
- CHECK_EQ(0, counting_message_handler_counter);
- v8::Debug::ProcessDebugMessages(isolate);
- // At least one message should come
- CHECK_GE(counting_message_handler_counter, 1);
-
- counting_message_handler_counter = 0;
-
- v8::Debug::SendCommand(
- isolate, buffer, AsciiToUtf16(scripts_command, buffer));
- v8::Debug::SendCommand(
- isolate, buffer, AsciiToUtf16(scripts_command, buffer));
- CHECK_EQ(0, counting_message_handler_counter);
- v8::Debug::ProcessDebugMessages(isolate);
- // At least two messages should come
- CHECK_GE(counting_message_handler_counter, 2);
-
- // Get rid of the debug message handler.
- v8::Debug::SetMessageHandler(isolate, nullptr);
- CheckDebuggerUnloaded(isolate);
-}
-
-
-class SendCommandThread;
-static SendCommandThread* send_command_thread_ = NULL;
-
-
-class SendCommandThread : public v8::base::Thread {
- public:
- explicit SendCommandThread(v8::Isolate* isolate)
- : Thread(Options("SendCommandThread")),
- semaphore_(0),
- isolate_(isolate) {}
-
- static void CountingAndSignallingMessageHandler(
- const v8::Debug::Message& message) {
- if (message.IsResponse()) {
- counting_message_handler_counter++;
- send_command_thread_->semaphore_.Signal();
- }
- }
-
- virtual void Run() {
- semaphore_.Wait();
- const int kBufferSize = 1000;
- uint16_t buffer[kBufferSize];
- const char* scripts_command =
- "{\"seq\":0,"
- "\"type\":\"request\","
- "\"command\":\"scripts\"}";
- int length = AsciiToUtf16(scripts_command, buffer);
- // Send scripts command.
-
- for (int i = 0; i < 20; i++) {
- v8::base::ElapsedTimer timer;
- timer.Start();
- CHECK_EQ(i, counting_message_handler_counter);
- // Queue debug message.
- v8::Debug::SendCommand(isolate_, buffer, length);
- // Wait for the message handler to pick up the response.
- semaphore_.Wait();
- i::PrintF("iteration %d took %f ms\n", i,
- timer.Elapsed().InMillisecondsF());
- }
-
- isolate_->TerminateExecution();
- }
-
- void StartSending() { semaphore_.Signal(); }
-
- private:
- v8::base::Semaphore semaphore_;
- v8::Isolate* isolate_;
-};
-
-
-static void StartSendingCommands(
- const v8::FunctionCallbackInfo<v8::Value>& info) {
- send_command_thread_->StartSending();
-}
-
-
-TEST(ProcessDebugMessagesThreaded) {
- DebugLocalContext env;
- v8::Isolate* isolate = env->GetIsolate();
- v8::HandleScope scope(isolate);
- v8::Local<v8::Context> context = env.context();
-
- counting_message_handler_counter = 0;
-
- v8::Debug::SetMessageHandler(
- isolate, SendCommandThread::CountingAndSignallingMessageHandler);
- send_command_thread_ = new SendCommandThread(isolate);
- send_command_thread_->Start();
-
- v8::Local<v8::FunctionTemplate> start =
- v8::FunctionTemplate::New(isolate, StartSendingCommands);
- CHECK(env->Global()
- ->Set(context, v8_str("start"),
- start->GetFunction(context).ToLocalChecked())
- .FromJust());
-
- CompileRun("start(); while (true) { }");
-
- CHECK_EQ(20, counting_message_handler_counter);
-
- v8::Debug::SetMessageHandler(isolate, nullptr);
- CheckDebuggerUnloaded(isolate);
-}
-
-
-struct BacktraceData {
- static int frame_counter;
- static void MessageHandler(const v8::Debug::Message& message) {
- char print_buffer[1000];
- v8::String::Value json(message.GetJSON());
- Utf16ToAscii(*json, json.length(), print_buffer, 1000);
-
- if (strstr(print_buffer, "backtrace") == NULL) {
- return;
- }
- frame_counter = GetTotalFramesInt(print_buffer);
- }
-};
-
-int BacktraceData::frame_counter;
-
-
-// Test that debug messages get processed when ProcessDebugMessages is called.
-TEST(Backtrace) {
- DebugLocalContext env;
- v8::Isolate* isolate = env->GetIsolate();
- v8::HandleScope scope(isolate);
- v8::Local<v8::Context> context = env.context();
-
- v8::Debug::SetMessageHandler(isolate, BacktraceData::MessageHandler);
-
- const int kBufferSize = 1000;
- uint16_t buffer[kBufferSize];
- const char* scripts_command =
- "{\"seq\":0,"
- "\"type\":\"request\","
- "\"command\":\"backtrace\"}";
-
- // Check backtrace from ProcessDebugMessages.
- BacktraceData::frame_counter = -10;
- v8::Debug::SendCommand(
- isolate,
- buffer,
- AsciiToUtf16(scripts_command, buffer),
- NULL);
- v8::Debug::ProcessDebugMessages(isolate);
- CHECK_EQ(BacktraceData::frame_counter, 0);
-
- v8::Local<v8::String> void0 = v8_str(env->GetIsolate(), "void(0)");
- v8::Local<v8::Script> script = CompileWithOrigin(void0, void0);
-
- // Check backtrace from "void(0)" script.
- BacktraceData::frame_counter = -10;
- v8::Debug::SendCommand(
- isolate,
- buffer,
- AsciiToUtf16(scripts_command, buffer),
- NULL);
- script->Run(context).ToLocalChecked();
- CHECK_EQ(BacktraceData::frame_counter, 1);
-
- // Get rid of the debug message handler.
- v8::Debug::SetMessageHandler(isolate, nullptr);
- CheckDebuggerUnloaded(isolate);
-}
-
-
-TEST(GetMirror) {
- DebugLocalContext env;
- v8::Isolate* isolate = env->GetIsolate();
- v8::HandleScope scope(isolate);
- v8::Local<v8::Context> context = env.context();
- v8::Local<v8::Value> obj =
- v8::Debug::GetMirror(context, v8_str(isolate, "hodja")).ToLocalChecked();
- v8::ScriptCompiler::Source source(v8_str(
- "function runTest(mirror) {"
- " return mirror.isString() && (mirror.length() == 5);"
- "}"
- ""
- "runTest;"));
- v8::Local<v8::Function> run_test = v8::Local<v8::Function>::Cast(
- v8::ScriptCompiler::CompileUnboundScript(isolate, &source)
- .ToLocalChecked()
- ->BindToCurrentContext()
- ->Run(context)
- .ToLocalChecked());
- v8::Local<v8::Value> result =
- run_test->Call(context, env->Global(), 1, &obj).ToLocalChecked();
- CHECK(result->IsTrue());
-}
-
-
// Test that the debug break flag works with function.apply.
TEST(DebugBreakFunctionApply) {
DebugLocalContext env;
@@ -7200,62 +5663,6 @@ TEST(CallingContextIsNotDebugContext) {
}
-TEST(DebugContextIsPreservedBetweenAccesses) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Debug::SetDebugEventListener(CcTest::isolate(),
- DebugEventBreakPointHitCount);
- v8::Local<v8::Context> context1 =
- v8::Debug::GetDebugContext(CcTest::isolate());
- v8::Local<v8::Context> context2 =
- v8::Debug::GetDebugContext(CcTest::isolate());
- CHECK(v8::Utils::OpenHandle(*context1).is_identical_to(
- v8::Utils::OpenHandle(*context2)));
- v8::Debug::SetDebugEventListener(CcTest::isolate(), nullptr);
-}
-
-
-TEST(NoDebugContextWhenDebuggerDisabled) {
- v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Context> context =
- v8::Debug::GetDebugContext(CcTest::isolate());
- CHECK(context.IsEmpty());
-}
-
-static void DebugEventCheckContext(
- const v8::Debug::EventDetails& event_details) {
- if (event_details.GetEvent() == v8::Break) {
- v8::Isolate* isolate = event_details.GetIsolate();
- CHECK(v8::Debug::GetDebuggedContext(isolate)
- .ToLocalChecked()
- ->Global()
- ->Equals(isolate->GetCurrentContext(),
- event_details.GetEventContext()->Global())
- .FromJust());
- }
-}
-
-static void CheckContext(const v8::FunctionCallbackInfo<v8::Value>& args) {
- CHECK(v8::Debug::GetDebuggedContext(args.GetIsolate()).IsEmpty());
-}
-
-TEST(DebuggedContext) {
- DebugLocalContext env;
- v8::Isolate* isolate = env->GetIsolate();
-
- v8::Debug::SetDebugEventListener(isolate, DebugEventCheckContext);
-
- v8::Local<v8::Function> foo =
- CompileFunction(&env, "function foo(){bar=0;}", "foo");
-
- SetBreakPoint(foo, 0);
- foo->Call(env.context(), env->Global(), 0, nullptr).ToLocalChecked();
-
- v8::Local<v8::Function> fun = v8::FunctionTemplate::New(isolate, CheckContext)
- ->GetFunction(env.context())
- .ToLocalChecked();
- fun->Call(env.context(), env->Global(), 0, nullptr).ToLocalChecked();
-}
-
static v8::Local<v8::Value> expected_callback_data;
static void DebugEventContextChecker(const v8::Debug::EventDetails& details) {
CHECK(details.GetEventContext() == expected_context);
@@ -8237,3 +6644,31 @@ TEST(DebugStepOverFunctionWithCaughtException) {
v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr);
CHECK_EQ(break_point_hit_count, 4);
}
+
+bool out_of_memory_callback_called = false;
+void OutOfMemoryCallback(void* data) {
+ out_of_memory_callback_called = true;
+ reinterpret_cast<v8::Isolate*>(data)->IncreaseHeapLimitForDebugging();
+}
+
+UNINITIALIZED_TEST(DebugSetOutOfMemoryListener) {
+ v8::Isolate::CreateParams create_params;
+ create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
+ create_params.constraints.set_max_old_space_size(10);
+ v8::Isolate* isolate = v8::Isolate::New(create_params);
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ {
+ v8::Isolate::Scope i_scope(isolate);
+ v8::HandleScope scope(isolate);
+ LocalContext context(isolate);
+ v8::debug::SetOutOfMemoryCallback(isolate, OutOfMemoryCallback,
+ reinterpret_cast<void*>(isolate));
+ CHECK(!out_of_memory_callback_called);
+ // The following allocation fails unless the out-of-memory callback
+ // increases the heap limit.
+ int length = 10 * i::MB / i::kPointerSize;
+ i_isolate->factory()->NewFixedArray(length, i::TENURED);
+ CHECK(out_of_memory_callback_called);
+ }
+ isolate->Dispose();
+}
diff --git a/deps/v8/test/cctest/test-disasm-arm.cc b/deps/v8/test/cctest/test-disasm-arm.cc
index 1c6d360d7f..3ba6bee8d4 100644
--- a/deps/v8/test/cctest/test-disasm-arm.cc
+++ b/deps/v8/test/cctest/test-disasm-arm.cc
@@ -936,10 +936,197 @@ TEST(Neon) {
"f3886a11 vmovl.u8 q3, d1");
COMPARE(vmovl(NeonU8, q4, d2),
"f3888a12 vmovl.u8 q4, d2");
+
+ COMPARE(vmov(NeonS8, d0, 0, r0), "ee400b10 vmov.8 d0[0], r0");
+ COMPARE(vmov(NeonU8, d1, 1, r1), "ee411b30 vmov.8 d1[1], r1");
+ COMPARE(vmov(NeonS8, d2, 2, r2), "ee422b50 vmov.8 d2[2], r2");
+ COMPARE(vmov(NeonU8, d3, 3, r8), "ee438b70 vmov.8 d3[3], r8");
+ COMPARE(vmov(NeonS8, d4, 4, r0), "ee640b10 vmov.8 d4[4], r0");
+ COMPARE(vmov(NeonU8, d5, 5, r1), "ee651b30 vmov.8 d5[5], r1");
+ COMPARE(vmov(NeonS8, d6, 6, r2), "ee662b50 vmov.8 d6[6], r2");
+ COMPARE(vmov(NeonU8, d7, 7, r8), "ee678b70 vmov.8 d7[7], r8");
+ COMPARE(vmov(NeonS16, d0, 0, r0), "ee000b30 vmov.16 d0[0], r0");
+ COMPARE(vmov(NeonS16, d1, 1, r1), "ee011b70 vmov.16 d1[1], r1");
+ COMPARE(vmov(NeonS16, d2, 2, r2), "ee222b30 vmov.16 d2[2], r2");
+ COMPARE(vmov(NeonS16, d3, 3, r7), "ee237b70 vmov.16 d3[3], r7");
+ COMPARE(vmov(NeonS32, d0, 0, r0), "ee000b10 vmov.32 d0[0], r0");
+ COMPARE(vmov(NeonU32, d0, 1, r0), "ee200b10 vmov.32 d0[1], r0");
+
+ COMPARE(vmov(NeonS8, r0, d0, 0), "ee500b10 vmov.s8 r0, d0[0]");
+ COMPARE(vmov(NeonU8, r1, d1, 1), "eed11b30 vmov.u8 r1, d1[1]");
+ COMPARE(vmov(NeonS8, r2, d2, 2), "ee522b50 vmov.s8 r2, d2[2]");
+ COMPARE(vmov(NeonU8, r8, d3, 3), "eed38b70 vmov.u8 r8, d3[3]");
+ COMPARE(vmov(NeonS8, r0, d4, 4), "ee740b10 vmov.s8 r0, d4[4]");
+ COMPARE(vmov(NeonU8, r1, d5, 5), "eef51b30 vmov.u8 r1, d5[5]");
+ COMPARE(vmov(NeonS8, r2, d6, 6), "ee762b50 vmov.s8 r2, d6[6]");
+ COMPARE(vmov(NeonU8, r8, d7, 7), "eef78b70 vmov.u8 r8, d7[7]");
+ COMPARE(vmov(NeonS16, r0, d0, 0), "ee100b30 vmov.s16 r0, d0[0]");
+ COMPARE(vmov(NeonU16, r1, d1, 1), "ee911b70 vmov.u16 r1, d1[1]");
+ COMPARE(vmov(NeonS16, r2, d2, 2), "ee322b30 vmov.s16 r2, d2[2]");
+ COMPARE(vmov(NeonU16, r7, d3, 3), "eeb37b70 vmov.u16 r7, d3[3]");
+ COMPARE(vmov(NeonS32, r2, d15, 0), "ee1f2b10 vmov.32 r2, d15[0]");
+ COMPARE(vmov(NeonS32, r3, d14, 1), "ee3e3b10 vmov.32 r3, d14[1]");
+
+ COMPARE(vmov(q0, q15),
+ "f22e01fe vmov q0, q15");
+ COMPARE(vmov(q8, q9),
+ "f26201f2 vmov q8, q9");
+ COMPARE(vmvn(q0, q15),
+ "f3b005ee vmvn q0, q15");
+ COMPARE(vmvn(q8, q9),
+ "f3f005e2 vmvn q8, q9");
COMPARE(vswp(d0, d31),
"f3b2002f vswp d0, d31");
COMPARE(vswp(d16, d14),
"f3f2000e vswp d16, d14");
+ COMPARE(vswp(q0, q15),
+ "f3b2006e vswp q0, q15");
+ COMPARE(vswp(q8, q9),
+ "f3f20062 vswp q8, q9");
+ COMPARE(vdup(Neon8, q0, r0),
+ "eee00b10 vdup.8 q0, r0");
+ COMPARE(vdup(Neon16, q1, r4),
+ "eea24b30 vdup.16 q1, r4");
+ COMPARE(vdup(Neon32, q15, r1),
+ "eeae1b90 vdup.32 q15, r1");
+ COMPARE(vdup(q0, s3),
+ "f3bc0c41 vdup q0, d1[1]");
+ COMPARE(vdup(q15, s2),
+ "f3f4ec41 vdup q15, d1[0]");
+ COMPARE(vcvt_f32_s32(q15, q1),
+ "f3fbe642 vcvt.f32.s32 q15, q1");
+ COMPARE(vcvt_f32_u32(q8, q9),
+ "f3fb06e2 vcvt.f32.u32 q8, q9");
+ COMPARE(vcvt_s32_f32(q15, q1),
+ "f3fbe742 vcvt.s32.f32 q15, q1");
+ COMPARE(vcvt_u32_f32(q8, q9),
+ "f3fb07e2 vcvt.u32.f32 q8, q9");
+ COMPARE(vabs(q0, q1),
+ "f3b90742 vabs.f32 q0, q1");
+ COMPARE(vabs(Neon8, q6, q7),
+ "f3b1c34e vabs.s8 q6, q7");
+ COMPARE(vabs(Neon16, q0, q1),
+ "f3b50342 vabs.s16 q0, q1");
+ COMPARE(vabs(Neon32, q0, q1),
+ "f3b90342 vabs.s32 q0, q1");
+ COMPARE(vneg(q0, q1),
+ "f3b907c2 vneg.f32 q0, q1");
+ COMPARE(vneg(Neon8, q6, q7),
+ "f3b1c3ce vneg.s8 q6, q7");
+ COMPARE(vneg(Neon16, q0, q1),
+ "f3b503c2 vneg.s16 q0, q1");
+ COMPARE(vneg(Neon32, q0, q1),
+ "f3b903c2 vneg.s32 q0, q1");
+ COMPARE(veor(d0, d1, d2),
+ "f3010112 veor d0, d1, d2");
+ COMPARE(veor(d0, d30, d31),
+ "f30e01bf veor d0, d30, d31");
+ COMPARE(veor(q0, q1, q2),
+ "f3020154 veor q0, q1, q2");
+ COMPARE(veor(q15, q0, q8),
+ "f340e170 veor q15, q0, q8");
+ COMPARE(vand(q15, q0, q8),
+ "f240e170 vand q15, q0, q8");
+ COMPARE(vorr(q15, q0, q8),
+ "f260e170 vorr q15, q0, q8");
+ COMPARE(vmin(q15, q0, q8),
+ "f260ef60 vmin.f32 q15, q0, q8");
+ COMPARE(vmax(q15, q0, q8),
+ "f240ef60 vmax.f32 q15, q0, q8");
+ COMPARE(vmax(NeonS8, q0, q1, q2),
+ "f2020644 vmax.s8 q0, q1, q2");
+ COMPARE(vmin(NeonU16, q1, q2, q8),
+ "f3142670 vmin.u16 q1, q2, q8");
+ COMPARE(vmax(NeonS32, q15, q0, q8),
+ "f260e660 vmax.s32 q15, q0, q8");
+ COMPARE(vadd(q15, q0, q8),
+ "f240ed60 vadd.f32 q15, q0, q8");
+ COMPARE(vadd(Neon8, q0, q1, q2),
+ "f2020844 vadd.i8 q0, q1, q2");
+ COMPARE(vadd(Neon16, q1, q2, q8),
+ "f2142860 vadd.i16 q1, q2, q8");
+ COMPARE(vadd(Neon32, q15, q0, q8),
+ "f260e860 vadd.i32 q15, q0, q8");
+ COMPARE(vsub(q15, q0, q8),
+ "f260ed60 vsub.f32 q15, q0, q8");
+ COMPARE(vsub(Neon8, q0, q1, q2),
+ "f3020844 vsub.i8 q0, q1, q2");
+ COMPARE(vsub(Neon16, q1, q2, q8),
+ "f3142860 vsub.i16 q1, q2, q8");
+ COMPARE(vsub(Neon32, q15, q0, q8),
+ "f360e860 vsub.i32 q15, q0, q8");
+ COMPARE(vmul(q0, q1, q2),
+ "f3020d54 vmul.f32 q0, q1, q2");
+ COMPARE(vmul(Neon8, q0, q1, q2),
+ "f2020954 vmul.i8 q0, q1, q2");
+ COMPARE(vmul(Neon16, q1, q2, q8),
+ "f2142970 vmul.i16 q1, q2, q8");
+ COMPARE(vmul(Neon32, q15, q0, q8),
+ "f260e970 vmul.i32 q15, q0, q8");
+ COMPARE(vrecpe(q15, q0),
+ "f3fbe540 vrecpe.f32 q15, q0");
+ COMPARE(vrecps(q15, q0, q8),
+ "f240ef70 vrecps.f32 q15, q0, q8");
+ COMPARE(vrsqrte(q15, q0),
+ "f3fbe5c0 vrsqrte.f32 q15, q0");
+ COMPARE(vrsqrts(q15, q0, q8),
+ "f260ef70 vrsqrts.f32 q15, q0, q8");
+ COMPARE(vtst(Neon8, q0, q1, q2),
+ "f2020854 vtst.i8 q0, q1, q2");
+ COMPARE(vtst(Neon16, q1, q2, q8),
+ "f2142870 vtst.i16 q1, q2, q8");
+ COMPARE(vtst(Neon32, q15, q0, q8),
+ "f260e870 vtst.i32 q15, q0, q8");
+ COMPARE(vceq(q0, q1, q2),
+ "f2020e44 vceq.f32 q0, q1, q2");
+ COMPARE(vcge(q0, q1, q2),
+ "f3020e44 vcge.f32 q0, q1, q2");
+ COMPARE(vcgt(q0, q1, q2),
+ "f3220e44 vcgt.f32 q0, q1, q2");
+ COMPARE(vceq(Neon8, q0, q1, q2),
+ "f3020854 vceq.i8 q0, q1, q2");
+ COMPARE(vceq(Neon16, q1, q2, q8),
+ "f3142870 vceq.i16 q1, q2, q8");
+ COMPARE(vceq(Neon32, q15, q0, q8),
+ "f360e870 vceq.i32 q15, q0, q8");
+ COMPARE(vcge(NeonS8, q0, q1, q2),
+ "f2020354 vcge.s8 q0, q1, q2");
+ COMPARE(vcge(NeonU16, q1, q2, q8),
+ "f3142370 vcge.u16 q1, q2, q8");
+ COMPARE(vcge(NeonS32, q15, q0, q8),
+ "f260e370 vcge.s32 q15, q0, q8");
+ COMPARE(vcgt(NeonS8, q0, q1, q2),
+ "f2020344 vcgt.s8 q0, q1, q2");
+ COMPARE(vcgt(NeonU16, q1, q2, q8),
+ "f3142360 vcgt.u16 q1, q2, q8");
+ COMPARE(vcgt(NeonS32, q15, q0, q8),
+ "f260e360 vcgt.s32 q15, q0, q8");
+ COMPARE(vbsl(q0, q1, q2),
+ "f3120154 vbsl q0, q1, q2");
+ COMPARE(vbsl(q15, q0, q8),
+ "f350e170 vbsl q15, q0, q8");
+ COMPARE(vext(q15, q0, q8, 3),
+ "f2f0e360 vext.8 q15, q0, q8, #3");
+ COMPARE(vzip(Neon16, q15, q0),
+ "f3f6e1c0 vzip.16 q15, q0");
+ COMPARE(vrev64(Neon8, q15, q0),
+ "f3f0e040 vrev64.8 q15, q0");
+ COMPARE(vtbl(d0, NeonListOperand(d1, 1), d2),
+ "f3b10802 vtbl.8 d0, {d1}, d2");
+ COMPARE(vtbl(d31, NeonListOperand(d0, 2), d4),
+ "f3f0f904 vtbl.8 d31, {d0, d1}, d4");
+ COMPARE(vtbl(d15, NeonListOperand(d1, 3), d5),
+ "f3b1fa05 vtbl.8 d15, {d1, d2, d3}, d5");
+ COMPARE(vtbl(d15, NeonListOperand(d1, 4), d5),
+ "f3b1fb05 vtbl.8 d15, {d1, d2, d3, d4}, d5");
+ COMPARE(vtbx(d0, NeonListOperand(d1, 1), d2),
+ "f3b10842 vtbx.8 d0, {d1}, d2");
+ COMPARE(vtbx(d31, NeonListOperand(d0, 2), d4),
+ "f3f0f944 vtbx.8 d31, {d0, d1}, d4");
+ COMPARE(vtbx(d15, NeonListOperand(d1, 3), d5),
+ "f3b1fa45 vtbx.8 d15, {d1, d2, d3}, d5");
+ COMPARE(vtbx(d15, NeonListOperand(d1, 4), d5),
+ "f3b1fb45 vtbx.8 d15, {d1, d2, d3, d4}, d5");
}
VERIFY_RUN();
diff --git a/deps/v8/test/cctest/test-extra.js b/deps/v8/test/cctest/test-extra.js
index 0cc4df4cc4..88c5f6e659 100644
--- a/deps/v8/test/cctest/test-extra.js
+++ b/deps/v8/test/cctest/test-extra.js
@@ -53,7 +53,8 @@
const fulfilledPromise = v8.createPromise();
v8.resolvePromise(
fulfilledPromise,
- hasOwn({ test: 'test' }, 'test') ? 1 : -1
+ hasOwn({ test: 'test' }, 'test') ? 1 : -1,
+ undefined // pass an extra arg to test arguments adapter frame
);
const fulfilledPromise2 = Promise_resolve(call(function (arg1, arg2) {
diff --git a/deps/v8/test/cctest/test-feedback-vector.cc b/deps/v8/test/cctest/test-feedback-vector.cc
index 1f9ddc6f55..8ff4997c01 100644
--- a/deps/v8/test/cctest/test-feedback-vector.cc
+++ b/deps/v8/test/cctest/test-feedback-vector.cc
@@ -95,6 +95,20 @@ TEST(VectorStructure) {
FeedbackVectorSlotKind::CALL_IC),
vector->length());
}
+
+ {
+ FeedbackVectorSpec spec(&zone);
+ spec.AddGeneralSlot();
+ spec.AddCreateClosureSlot(5);
+ spec.AddGeneralSlot();
+ vector = NewTypeFeedbackVector(isolate, &spec);
+ FeedbackVectorHelper helper(vector);
+ CHECK_EQ(1, TypeFeedbackMetadata::GetSlotSize(
+ FeedbackVectorSlotKind::CREATE_CLOSURE));
+ FeedbackVectorSlot slot = helper.slot(1);
+ FixedArray* array = FixedArray::cast(vector->Get(slot));
+ CHECK_EQ(array, *factory->empty_literals_array());
+ }
}
diff --git a/deps/v8/test/cctest/test-field-type-tracking.cc b/deps/v8/test/cctest/test-field-type-tracking.cc
index df6a06bfc7..4abde16cd6 100644
--- a/deps/v8/test/cctest/test-field-type-tracking.cc
+++ b/deps/v8/test/cctest/test-field-type-tracking.cc
@@ -73,23 +73,12 @@ static Handle<AccessorPair> CreateAccessorPair(bool with_getter,
}
-static bool EqualDetails(DescriptorArray* descriptors, int descriptor,
- PropertyType type, PropertyAttributes attributes,
- Representation representation, int field_index = -1) {
- PropertyDetails details = descriptors->GetDetails(descriptor);
- if (details.type() != type) return false;
- if (details.attributes() != attributes) return false;
- if (!details.representation().Equals(representation)) return false;
- if (field_index >= 0 && details.field_index() != field_index) return false;
- return true;
-}
-
-
class Expectations {
static const int MAX_PROPERTIES = 10;
Isolate* isolate_;
ElementsKind elements_kind_;
- PropertyType types_[MAX_PROPERTIES];
+ PropertyKind kinds_[MAX_PROPERTIES];
+ PropertyLocation locations_[MAX_PROPERTIES];
PropertyAttributes attributes_[MAX_PROPERTIES];
Representation representations_[MAX_PROPERTIES];
// FieldType for kField, value for DATA_CONSTANT and getter for
@@ -110,10 +99,12 @@ class Expectations {
isolate,
isolate->object_function()->initial_map()->elements_kind()) {}
- void Init(int index, PropertyType type, PropertyAttributes attributes,
- Representation representation, Handle<Object> value) {
+ void Init(int index, PropertyKind kind, PropertyAttributes attributes,
+ PropertyLocation location, Representation representation,
+ Handle<Object> value) {
CHECK(index < MAX_PROPERTIES);
- types_[index] = type;
+ kinds_[index] = kind;
+ locations_[index] = location;
attributes_[index] = attributes;
representations_[index] = representation;
values_[index] = value;
@@ -125,29 +116,23 @@ class Expectations {
for (int i = 0; i < number_of_properties_; i++) {
os << " " << i << ": ";
os << "Descriptor @ ";
- if (types_[i] == ACCESSOR_CONSTANT) {
+
+ if (kinds_[i] == kData) {
+ os << Brief(*values_[i]);
+ } else {
+ // kAccessor
os << "(get: " << Brief(*values_[i])
<< ", set: " << Brief(*setter_values_[i]) << ") ";
- } else {
- os << Brief(*values_[i]);
}
+
os << " (";
- switch (types_[i]) {
- case DATA_CONSTANT:
- os << "immutable ";
- // Fall through.
- case DATA:
- os << "data";
- break;
-
- case ACCESSOR_CONSTANT:
- os << "immutable ";
- // Fall through.
- case ACCESSOR:
- os << "accessor";
- break;
+ os << (kinds_[i] == kData ? "data " : "accessor ");
+ if (locations_[i] == kField) {
+ os << "field"
+ << ": " << representations_[i].Mnemonic();
+ } else {
+ os << "descriptor";
}
- os << ": " << representations_[i].Mnemonic();
os << ", attrs: " << attributes_[i] << ")\n";
}
os << "\n";
@@ -159,22 +144,23 @@ class Expectations {
Handle<FieldType> GetFieldType(int index) {
CHECK(index < MAX_PROPERTIES);
- CHECK(types_[index] == DATA || types_[index] == ACCESSOR);
+ CHECK_EQ(kField, locations_[index]);
return Handle<FieldType>::cast(values_[index]);
}
void SetDataField(int index, PropertyAttributes attrs,
- Representation representation, Handle<FieldType> value) {
- Init(index, DATA, attrs, representation, value);
+ Representation representation,
+ Handle<FieldType> field_type) {
+ Init(index, kData, attrs, kField, representation, field_type);
}
void SetDataField(int index, Representation representation,
- Handle<FieldType> value) {
- SetDataField(index, attributes_[index], representation, value);
+ Handle<FieldType> field_type) {
+ SetDataField(index, attributes_[index], representation, field_type);
}
void SetAccessorField(int index, PropertyAttributes attrs) {
- Init(index, ACCESSOR, attrs, Representation::Tagged(),
+ Init(index, kAccessor, attrs, kDescriptor, Representation::Tagged(),
FieldType::Any(isolate_));
}
@@ -184,7 +170,7 @@ class Expectations {
void SetDataConstant(int index, PropertyAttributes attrs,
Handle<JSFunction> value) {
- Init(index, DATA_CONSTANT, attrs, Representation::HeapObject(), value);
+ Init(index, kData, attrs, kDescriptor, Representation::HeapObject(), value);
}
void SetDataConstant(int index, Handle<JSFunction> value) {
@@ -193,14 +179,16 @@ class Expectations {
void SetAccessorConstant(int index, PropertyAttributes attrs,
Handle<Object> getter, Handle<Object> setter) {
- Init(index, ACCESSOR_CONSTANT, attrs, Representation::Tagged(), getter);
+ Init(index, kAccessor, attrs, kDescriptor, Representation::Tagged(),
+ getter);
setter_values_[index] = setter;
}
void SetAccessorConstantComponent(int index, PropertyAttributes attrs,
AccessorComponent component,
Handle<Object> accessor) {
- CHECK_EQ(ACCESSOR_CONSTANT, types_[index]);
+ CHECK_EQ(kAccessor, kinds_[index]);
+ CHECK_EQ(kDescriptor, locations_[index]);
CHECK(index < number_of_properties_);
if (component == ACCESSOR_GETTER) {
values_[index] = accessor;
@@ -230,31 +218,41 @@ class Expectations {
void GeneralizeRepresentation(int index) {
CHECK(index < number_of_properties_);
representations_[index] = Representation::Tagged();
- if (types_[index] == DATA || types_[index] == ACCESSOR) {
+ if (locations_[index] == kField) {
values_[index] = FieldType::Any(isolate_);
}
}
bool Check(DescriptorArray* descriptors, int descriptor) const {
- PropertyType type = types_[descriptor];
- if (!EqualDetails(descriptors, descriptor, type, attributes_[descriptor],
- representations_[descriptor])) {
- return false;
- }
+ PropertyDetails details = descriptors->GetDetails(descriptor);
+
+ if (details.kind() != kinds_[descriptor]) return false;
+ if (details.location() != locations_[descriptor]) return false;
+
+ PropertyAttributes expected_attributes = attributes_[descriptor];
+ if (details.attributes() != expected_attributes) return false;
+
+ Representation expected_representation = representations_[descriptor];
+ if (!details.representation().Equals(expected_representation)) return false;
+
Object* value = descriptors->GetValue(descriptor);
Object* expected_value = *values_[descriptor];
- switch (type) {
- case DATA:
- case ACCESSOR: {
+ if (details.location() == kField) {
+ if (details.kind() == kData) {
FieldType* type = descriptors->GetFieldType(descriptor);
return FieldType::cast(expected_value) == type;
+ } else {
+ // kAccessor
+ UNREACHABLE();
+ return false;
}
-
- case DATA_CONSTANT:
+ } else {
+ // kDescriptor
+ if (details.kind() == kData) {
return value == expected_value;
-
- case ACCESSOR_CONSTANT: {
+ } else {
+ // kAccessor
if (value == expected_value) return true;
if (!value->IsAccessorPair()) return false;
AccessorPair* pair = AccessorPair::cast(value);
@@ -376,8 +374,8 @@ class Expectations {
Handle<String> name = MakeName("prop", property_index);
- AccessorConstantDescriptor new_desc(name, pair, attributes);
- return Map::CopyInsertDescriptor(map, &new_desc, INSERT_TRANSITION);
+ Descriptor d = Descriptor::AccessorConstant(name, pair, attributes);
+ return Map::CopyInsertDescriptor(map, &d, INSERT_TRANSITION);
}
Handle<Map> AddAccessorConstant(Handle<Map> map,
@@ -396,14 +394,14 @@ class Expectations {
if (!getter->IsNull(isolate_)) {
Handle<AccessorPair> pair = factory->NewAccessorPair();
pair->SetComponents(*getter, *factory->null_value());
- AccessorConstantDescriptor new_desc(name, pair, attributes);
- map = Map::CopyInsertDescriptor(map, &new_desc, INSERT_TRANSITION);
+ Descriptor d = Descriptor::AccessorConstant(name, pair, attributes);
+ map = Map::CopyInsertDescriptor(map, &d, INSERT_TRANSITION);
}
if (!setter->IsNull(isolate_)) {
Handle<AccessorPair> pair = factory->NewAccessorPair();
pair->SetComponents(*getter, *setter);
- AccessorConstantDescriptor new_desc(name, pair, attributes);
- map = Map::CopyInsertDescriptor(map, &new_desc, INSERT_TRANSITION);
+ Descriptor d = Descriptor::AccessorConstant(name, pair, attributes);
+ map = Map::CopyInsertDescriptor(map, &d, INSERT_TRANSITION);
}
return map;
}
@@ -457,7 +455,7 @@ TEST(ReconfigureAccessorToNonExistingDataField) {
CHECK(expectations.Check(*map));
Handle<Map> new_map = Map::ReconfigureProperty(
- map, 0, kData, NONE, Representation::None(), none_type, FORCE_FIELD);
+ map, 0, kData, NONE, Representation::None(), none_type);
// |map| did not change except marked unstable.
CHECK(!map->is_deprecated());
CHECK(!map->is_stable());
@@ -470,7 +468,7 @@ TEST(ReconfigureAccessorToNonExistingDataField) {
CHECK(expectations.Check(*new_map));
Handle<Map> new_map2 = Map::ReconfigureProperty(
- map, 0, kData, NONE, Representation::None(), none_type, FORCE_FIELD);
+ map, 0, kData, NONE, Representation::None(), none_type);
CHECK_EQ(*new_map, *new_map2);
Handle<Object> value(Smi::kZero, isolate);
@@ -594,7 +592,7 @@ static void TestGeneralizeRepresentation(
if (is_detached_map) {
detach_point_map = Map::ReconfigureProperty(
detach_point_map, detach_property_at_index, kData, NONE,
- Representation::Tagged(), any_type, FORCE_FIELD);
+ Representation::Tagged(), any_type);
expectations.SetDataField(detach_property_at_index,
Representation::Tagged(), any_type);
CHECK(map->is_deprecated());
@@ -609,9 +607,8 @@ static void TestGeneralizeRepresentation(
dependencies.AssumeFieldOwner(field_owner);
- Handle<Map> new_map =
- Map::ReconfigureProperty(map, property_index, kData, NONE,
- to_representation, to_type, FORCE_FIELD);
+ Handle<Map> new_map = Map::ReconfigureProperty(
+ map, property_index, kData, NONE, to_representation, to_type);
expectations.SetDataField(property_index, expected_representation,
expected_type);
@@ -902,7 +899,7 @@ TEST(GeneralizeRepresentationWithAccessorProperties) {
continue;
}
Handle<Map> new_map = Map::ReconfigureProperty(
- map, i, kData, NONE, Representation::Double(), any_type, FORCE_FIELD);
+ map, i, kData, NONE, Representation::Double(), any_type);
maps[i] = new_map;
expectations.SetDataField(i, Representation::Double(), any_type);
@@ -1239,7 +1236,7 @@ struct CheckUnrelated {
// Checks that given |map| is NOT deprecated, and |new_map| is a result of
// copy-generalize-all-representations.
-struct CheckCopyGeneralizeAllRepresentations {
+struct CheckCopyGeneralizeAllFields {
void Check(Handle<Map> map, Handle<Map> new_map, Expectations& expectations) {
CHECK(!map->is_deprecated());
CHECK_NE(*map, *new_map);
@@ -1379,11 +1376,23 @@ TEST(ReconfigureDataFieldAttribute_DataConstantToDataFieldAfterTargetMap) {
struct TestConfig {
Handle<JSFunction> js_func1_;
Handle<JSFunction> js_func2_;
+ Handle<FieldType> function_type_;
TestConfig() {
Isolate* isolate = CcTest::i_isolate();
Factory* factory = isolate->factory();
- js_func1_ = factory->NewFunction(factory->empty_string());
- js_func2_ = factory->NewFunction(factory->empty_string());
+ Handle<String> name = factory->empty_string();
+ Handle<Map> sloppy_map =
+ factory->CreateSloppyFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE);
+ Handle<SharedFunctionInfo> info = factory->NewSharedFunctionInfo(
+ name, MaybeHandle<Code>(), sloppy_map->is_constructor());
+ function_type_ = FieldType::Class(sloppy_map, isolate);
+ CHECK(sloppy_map->is_stable());
+
+ js_func1_ =
+ factory->NewFunction(sloppy_map, info, isolate->native_context());
+
+ js_func2_ =
+ factory->NewFunction(sloppy_map, info, isolate->native_context());
}
Handle<Map> AddPropertyAtBranch(int branch_id, Expectations& expectations,
@@ -1394,11 +1403,8 @@ TEST(ReconfigureDataFieldAttribute_DataConstantToDataFieldAfterTargetMap) {
}
void UpdateExpectations(int property_index, Expectations& expectations) {
- Isolate* isolate = CcTest::i_isolate();
- Handle<FieldType> function_type =
- FieldType::Class(isolate->sloppy_function_map(), isolate);
expectations.SetDataField(property_index, Representation::HeapObject(),
- function_type);
+ function_type_);
}
};
@@ -1502,11 +1508,11 @@ TEST(ReconfigureDataFieldAttribute_AccConstantToAccFieldAfterTargetMap) {
TestConfig config;
if (IS_ACCESSOR_FIELD_SUPPORTED) {
- CheckCopyGeneralizeAllRepresentations checker;
+ CheckCopyGeneralizeAllFields checker;
TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker);
} else {
// Currently we have a copy-generalize-all-representations case.
- CheckCopyGeneralizeAllRepresentations checker;
+ CheckCopyGeneralizeAllFields checker;
TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker);
}
}
@@ -1847,8 +1853,7 @@ TEST(ReconfigurePropertySplitMapTransitionsOverflow) {
}
map2 = Map::ReconfigureProperty(map2, kSplitProp, kData, NONE,
- Representation::Double(), any_type,
- FORCE_FIELD);
+ Representation::Double(), any_type);
expectations.SetDataField(kSplitProp, Representation::Double(), any_type);
CHECK(expectations.Check(*split_map, kSplitProp));
@@ -1947,8 +1952,8 @@ static void TestGeneralizeRepresentationWithSpecialTransition(
// Create new maps by generalizing representation of propX field.
Handle<Map> maps[kPropCount];
for (int i = 0; i < kPropCount; i++) {
- Handle<Map> new_map = Map::ReconfigureProperty(
- map, i, kData, NONE, to_representation, to_type, FORCE_FIELD);
+ Handle<Map> new_map = Map::ReconfigureProperty(map, i, kData, NONE,
+ to_representation, to_type);
maps[i] = new_map;
expectations.SetDataField(i, expected_representation, expected_type);
@@ -2365,13 +2370,20 @@ TEST(TransitionDataConstantToAnotherDataConstant) {
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
Factory* factory = isolate->factory();
- Handle<FieldType> function_type =
- FieldType::Class(isolate->sloppy_function_map(), isolate);
-
- Handle<JSFunction> js_func1 = factory->NewFunction(factory->empty_string());
+ Handle<String> name = factory->empty_string();
+ Handle<Map> sloppy_map =
+ factory->CreateSloppyFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE);
+ Handle<SharedFunctionInfo> info = factory->NewSharedFunctionInfo(
+ name, MaybeHandle<Code>(), sloppy_map->is_constructor());
+ Handle<FieldType> function_type = FieldType::Class(sloppy_map, isolate);
+ CHECK(sloppy_map->is_stable());
+
+ Handle<JSFunction> js_func1 =
+ factory->NewFunction(sloppy_map, info, isolate->native_context());
TransitionToDataConstantOperator transition_op1(js_func1);
- Handle<JSFunction> js_func2 = factory->NewFunction(factory->empty_string());
+ Handle<JSFunction> js_func2 =
+ factory->NewFunction(sloppy_map, info, isolate->native_context());
TransitionToDataConstantOperator transition_op2(js_func2);
FieldGeneralizationChecker checker(
diff --git a/deps/v8/test/cctest/test-flags.cc b/deps/v8/test/cctest/test-flags.cc
index fd49dae1e9..230b3d1dd0 100644
--- a/deps/v8/test/cctest/test-flags.cc
+++ b/deps/v8/test/cctest/test-flags.cc
@@ -252,7 +252,7 @@ TEST(FlagsRemoveIncomplete) {
// if the list of arguments ends unexpectedly.
SetFlagsToDefault();
int argc = 3;
- const char* argv[] = { "", "--crankshaft", "--expose-debug-as" };
+ const char* argv[] = {"", "--crankshaft", "--expose-natives-as"};
CHECK_EQ(2, FlagList::SetFlagsFromCommandLine(&argc,
const_cast<char **>(argv),
true));
diff --git a/deps/v8/test/cctest/test-global-handles.cc b/deps/v8/test/cctest/test-global-handles.cc
index 256b74c616..2ace0296c1 100644
--- a/deps/v8/test/cctest/test-global-handles.cc
+++ b/deps/v8/test/cctest/test-global-handles.cc
@@ -29,6 +29,7 @@
#include "src/factory.h"
#include "src/global-handles.h"
#include "src/isolate.h"
+#include "src/objects-inl.h"
#include "src/objects.h"
#include "test/cctest/cctest.h"
diff --git a/deps/v8/test/cctest/test-global-object.cc b/deps/v8/test/cctest/test-global-object.cc
index d6713208bf..9f32e05121 100644
--- a/deps/v8/test/cctest/test-global-object.cc
+++ b/deps/v8/test/cctest/test-global-object.cc
@@ -26,6 +26,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "src/api.h"
+#include "src/objects-inl.h"
#include "src/v8.h"
#include "test/cctest/cctest.h"
@@ -105,3 +106,30 @@ TEST(KeysGlobalObject_Regress2764) {
Local<Array>::Cast(CompileRun("Object.getOwnPropertyNames(global2)"));
CHECK_EQ(0u, result->Length());
}
+
+TEST(KeysGlobalObject_SetPrototype) {
+ LocalContext env1;
+ v8::HandleScope scope(env1->GetIsolate());
+
+ // Create second environment.
+ v8::Local<Context> env2 = Context::New(env1->GetIsolate());
+
+ Local<Value> token = v8_str("foo");
+
+ // Set same security token for env1 and env2.
+ env1->SetSecurityToken(token);
+ env2->SetSecurityToken(token);
+
+ // Create a reference to env2 global from env1 global.
+ env1->Global()
+ ->GetPrototype()
+ .As<v8::Object>()
+ ->SetPrototype(env1.local(), env2->Global()->GetPrototype())
+ .FromJust();
+ // Set some global variables in global2
+ env2->Global()->Set(env2, v8_str("a"), v8_str("a")).FromJust();
+ env2->Global()->Set(env2, v8_str("42"), v8_str("42")).FromJust();
+
+ // List all entries from global2.
+ ExpectTrue("a == 'a'");
+}
diff --git a/deps/v8/test/cctest/test-heap-profiler.cc b/deps/v8/test/cctest/test-heap-profiler.cc
index 9721477b28..9780b3f519 100644
--- a/deps/v8/test/cctest/test-heap-profiler.cc
+++ b/deps/v8/test/cctest/test-heap-profiler.cc
@@ -69,10 +69,10 @@ class NamedEntriesDetector {
CheckEntry(root);
while (!list.is_empty()) {
i::HeapEntry* entry = list.RemoveLast();
- i::Vector<i::HeapGraphEdge*> children = entry->children();
- for (int i = 0; i < children.length(); ++i) {
- if (children[i]->type() == i::HeapGraphEdge::kShortcut) continue;
- i::HeapEntry* child = children[i]->to();
+ for (int i = 0; i < entry->children_count(); ++i) {
+ i::HeapGraphEdge* edge = entry->child(i);
+ if (edge->type() == i::HeapGraphEdge::kShortcut) continue;
+ i::HeapEntry* child = edge->to();
v8::base::HashMap::Entry* entry = visited.LookupOrInsert(
reinterpret_cast<void*>(child),
static_cast<uint32_t>(reinterpret_cast<uintptr_t>(child)));
@@ -137,8 +137,8 @@ static bool ValidateSnapshot(const v8::HeapSnapshot* snapshot, int depth = 3) {
reinterpret_cast<const i::HeapSnapshot*>(snapshot));
v8::base::HashMap visited;
- i::List<i::HeapGraphEdge>& edges = heap_snapshot->edges();
- for (int i = 0; i < edges.length(); ++i) {
+ std::deque<i::HeapGraphEdge>& edges = heap_snapshot->edges();
+ for (size_t i = 0; i < edges.size(); ++i) {
v8::base::HashMap::Entry* entry = visited.LookupOrInsert(
reinterpret_cast<void*>(edges[i].to()),
static_cast<uint32_t>(reinterpret_cast<uintptr_t>(edges[i].to())));
@@ -1570,88 +1570,6 @@ TEST(HeapSnapshotRetainedObjectInfo) {
CHECK_EQ(ccc, GetProperty(n_CCC, v8::HeapGraphEdge::kInternal, "native"));
}
-
-class GraphWithImplicitRefs {
- public:
- static const int kObjectsCount = 4;
- explicit GraphWithImplicitRefs(LocalContext* env) {
- CHECK(!instance_);
- instance_ = this;
- isolate_ = (*env)->GetIsolate();
- for (int i = 0; i < kObjectsCount; i++) {
- objects_[i].Reset(isolate_, v8::Object::New(isolate_));
- }
- (*env)
- ->Global()
- ->Set(isolate_->GetCurrentContext(), v8_str("root_object"),
- v8::Local<v8::Value>::New(isolate_, objects_[0]))
- .FromJust();
- }
- ~GraphWithImplicitRefs() {
- instance_ = NULL;
- }
-
- static void gcPrologue(v8::Isolate* isolate, v8::GCType type,
- v8::GCCallbackFlags flags) {
- instance_->AddImplicitReferences();
- }
-
- private:
- void AddImplicitReferences() {
- // 0 -> 1
- isolate_->SetObjectGroupId(objects_[0],
- v8::UniqueId(1));
- isolate_->SetReferenceFromGroup(
- v8::UniqueId(1), objects_[1]);
- // Adding two more references: 1 -> 2, 1 -> 3
- isolate_->SetReference(objects_[1].As<v8::Object>(),
- objects_[2]);
- isolate_->SetReference(objects_[1].As<v8::Object>(),
- objects_[3]);
- }
-
- v8::Persistent<v8::Value> objects_[kObjectsCount];
- static GraphWithImplicitRefs* instance_;
- v8::Isolate* isolate_;
-};
-
-GraphWithImplicitRefs* GraphWithImplicitRefs::instance_ = NULL;
-
-
-TEST(HeapSnapshotImplicitReferences) {
- LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
- v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler();
-
- GraphWithImplicitRefs graph(&env);
- env->GetIsolate()->AddGCPrologueCallback(&GraphWithImplicitRefs::gcPrologue);
-
- const v8::HeapSnapshot* snapshot = heap_profiler->TakeHeapSnapshot();
- CHECK(ValidateSnapshot(snapshot));
-
- const v8::HeapGraphNode* global_object = GetGlobalObject(snapshot);
- const v8::HeapGraphNode* obj0 = GetProperty(
- global_object, v8::HeapGraphEdge::kProperty, "root_object");
- CHECK(obj0);
- CHECK_EQ(v8::HeapGraphNode::kObject, obj0->GetType());
- const v8::HeapGraphNode* obj1 = GetProperty(
- obj0, v8::HeapGraphEdge::kInternal, "native");
- CHECK(obj1);
- int implicit_targets_count = 0;
- for (int i = 0, count = obj1->GetChildrenCount(); i < count; ++i) {
- const v8::HeapGraphEdge* prop = obj1->GetChild(i);
- v8::String::Utf8Value prop_name(prop->GetName());
- if (prop->GetType() == v8::HeapGraphEdge::kInternal &&
- strcmp("native", *prop_name) == 0) {
- ++implicit_targets_count;
- }
- }
- CHECK_EQ(2, implicit_targets_count);
- env->GetIsolate()->RemoveGCPrologueCallback(
- &GraphWithImplicitRefs::gcPrologue);
-}
-
-
TEST(DeleteAllHeapSnapshots) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -2568,7 +2486,7 @@ TEST(TrackHeapAllocationsWithInlining) {
const char* names[] = {"", "start", "f_0_0"};
AllocationTraceNode* node = FindNode(tracker, ArrayVector(names));
CHECK(node);
- CHECK_GE(node->allocation_count(), 12u);
+ CHECK_GE(node->allocation_count(), 10u);
CHECK_GE(node->allocation_size(), 4 * node->allocation_count());
heap_profiler->StopTrackingHeapObjects();
}
diff --git a/deps/v8/test/cctest/test-inobject-slack-tracking.cc b/deps/v8/test/cctest/test-inobject-slack-tracking.cc
index 9f33d55938..3c46fbee06 100644
--- a/deps/v8/test/cctest/test-inobject-slack-tracking.cc
+++ b/deps/v8/test/cctest/test-inobject-slack-tracking.cc
@@ -7,6 +7,7 @@
#include <utility>
#include "src/api.h"
+#include "src/objects-inl.h"
#include "src/objects.h"
#include "src/v8.h"
@@ -1099,10 +1100,8 @@ TEST(SubclassPromiseBuiltin) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
- const int first_field = 5;
TestSubclassBuiltin("A1", JS_PROMISE_TYPE, "Promise",
- "function(resolve, reject) { resolve('ok'); }",
- first_field);
+ "function(resolve, reject) { resolve('ok'); }");
}
diff --git a/deps/v8/test/cctest/test-javascript-arm64.cc b/deps/v8/test/cctest/test-javascript-arm64.cc
index aa4988ef06..d23b63e0a9 100644
--- a/deps/v8/test/cctest/test-javascript-arm64.cc
+++ b/deps/v8/test/cctest/test-javascript-arm64.cc
@@ -34,6 +34,7 @@
#include "src/compilation-cache.h"
#include "src/execution.h"
#include "src/isolate.h"
+#include "src/objects-inl.h"
#include "src/unicode-inl.h"
#include "src/utils.h"
#include "test/cctest/cctest.h"
diff --git a/deps/v8/test/cctest/test-js-arm64-variables.cc b/deps/v8/test/cctest/test-js-arm64-variables.cc
index f6958fd422..dbcf8f94ac 100644
--- a/deps/v8/test/cctest/test-js-arm64-variables.cc
+++ b/deps/v8/test/cctest/test-js-arm64-variables.cc
@@ -36,6 +36,7 @@
#include "src/compilation-cache.h"
#include "src/execution.h"
#include "src/isolate.h"
+#include "src/objects-inl.h"
#include "src/unicode-inl.h"
#include "src/utils.h"
#include "test/cctest/cctest.h"
diff --git a/deps/v8/test/cctest/test-liveedit.cc b/deps/v8/test/cctest/test-liveedit.cc
index 7525676b84..cde9e92331 100644
--- a/deps/v8/test/cctest/test-liveedit.cc
+++ b/deps/v8/test/cctest/test-liveedit.cc
@@ -30,6 +30,7 @@
#include "src/v8.h"
#include "src/debug/liveedit.h"
+#include "src/objects-inl.h"
#include "test/cctest/cctest.h"
diff --git a/deps/v8/test/cctest/test-lockers.cc b/deps/v8/test/cctest/test-lockers.cc
index 4d4f3e2177..30fba8ac98 100644
--- a/deps/v8/test/cctest/test-lockers.cc
+++ b/deps/v8/test/cctest/test-lockers.cc
@@ -36,6 +36,7 @@
#include "src/compilation-cache.h"
#include "src/execution.h"
#include "src/isolate.h"
+#include "src/objects-inl.h"
#include "src/unicode-inl.h"
#include "src/utils.h"
#include "test/cctest/cctest.h"
@@ -686,12 +687,9 @@ class IsolateGenesisThread : public JoinableThread {
v8::Isolate* isolate = v8::Isolate::New(create_params);
{
v8::Isolate::Scope isolate_scope(isolate);
- CHECK(
- !reinterpret_cast<i::Isolate*>(isolate)->has_installed_extensions());
v8::ExtensionConfiguration extensions(count_, extension_names_);
v8::HandleScope handle_scope(isolate);
v8::Context::New(isolate, &extensions);
- CHECK(reinterpret_cast<i::Isolate*>(isolate)->has_installed_extensions());
}
isolate->Dispose();
}
diff --git a/deps/v8/test/cctest/test-log.cc b/deps/v8/test/cctest/test-log.cc
index 91029286f7..f208c5a7b6 100644
--- a/deps/v8/test/cctest/test-log.cc
+++ b/deps/v8/test/cctest/test-log.cc
@@ -37,6 +37,7 @@
#include "src/api.h"
#include "src/log-utils.h"
#include "src/log.h"
+#include "src/objects-inl.h"
#include "src/profiler/cpu-profiler.h"
#include "src/snapshot/natives.h"
#include "src/utils.h"
diff --git a/deps/v8/test/cctest/test-macro-assembler-arm.cc b/deps/v8/test/cctest/test-macro-assembler-arm.cc
index 06efc58cfa..63919a46cc 100644
--- a/deps/v8/test/cctest/test-macro-assembler-arm.cc
+++ b/deps/v8/test/cctest/test-macro-assembler-arm.cc
@@ -42,6 +42,7 @@ typedef void* (*F)(int x, int y, int p2, int p3, int p4);
#define __ masm->
+typedef Object* (*F3)(void* p0, int p1, int p2, int p3, int p4);
typedef int (*F5)(void*, void*, void*, void*, void*);
@@ -134,4 +135,359 @@ TEST(LoadAndStoreWithRepresentation) {
CHECK(!CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
}
+TEST(ExtractLane) {
+ if (!CpuFeatures::IsSupported(NEON)) return;
+
+ // Allocate an executable page of memory.
+ size_t actual_size;
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
+ CHECK(buffer);
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope handles(isolate);
+ MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size),
+ v8::internal::CodeObjectRequired::kYes);
+ MacroAssembler* masm = &assembler; // Create a pointer for the __ macro.
+
+ typedef struct {
+ int32_t i32x4_low[4];
+ int32_t i32x4_high[4];
+ int32_t i16x8_low[8];
+ int32_t i16x8_high[8];
+ int32_t i8x16_low[16];
+ int32_t i8x16_high[16];
+ int32_t f32x4_low[4];
+ int32_t f32x4_high[4];
+ } T;
+ T t;
+
+ __ stm(db_w, sp, r4.bit() | r5.bit() | lr.bit());
+
+ for (int i = 0; i < 4; i++) {
+ __ mov(r4, Operand(i));
+ __ vdup(Neon32, q1, r4);
+ __ ExtractLane(r5, q1, NeonS32, i);
+ __ str(r5, MemOperand(r0, offsetof(T, i32x4_low) + 4 * i));
+ SwVfpRegister si = SwVfpRegister::from_code(i);
+ __ ExtractLane(si, q1, r4, i);
+ __ vstr(si, r0, offsetof(T, f32x4_low) + 4 * i);
+ }
+
+ for (int i = 0; i < 8; i++) {
+ __ mov(r4, Operand(i));
+ __ vdup(Neon16, q1, r4);
+ __ ExtractLane(r5, q1, NeonS16, i);
+ __ str(r5, MemOperand(r0, offsetof(T, i16x8_low) + 4 * i));
+ }
+
+ for (int i = 0; i < 16; i++) {
+ __ mov(r4, Operand(i));
+ __ vdup(Neon8, q1, r4);
+ __ ExtractLane(r5, q1, NeonS8, i);
+ __ str(r5, MemOperand(r0, offsetof(T, i8x16_low) + 4 * i));
+ }
+
+ if (CpuFeatures::IsSupported(VFP32DREGS)) {
+ for (int i = 0; i < 4; i++) {
+ __ mov(r4, Operand(-i));
+ __ vdup(Neon32, q15, r4);
+ __ ExtractLane(r5, q15, NeonS32, i);
+ __ str(r5, MemOperand(r0, offsetof(T, i32x4_high) + 4 * i));
+ SwVfpRegister si = SwVfpRegister::from_code(i);
+ __ ExtractLane(si, q15, r4, i);
+ __ vstr(si, r0, offsetof(T, f32x4_high) + 4 * i);
+ }
+
+ for (int i = 0; i < 8; i++) {
+ __ mov(r4, Operand(-i));
+ __ vdup(Neon16, q15, r4);
+ __ ExtractLane(r5, q15, NeonS16, i);
+ __ str(r5, MemOperand(r0, offsetof(T, i16x8_high) + 4 * i));
+ }
+
+ for (int i = 0; i < 16; i++) {
+ __ mov(r4, Operand(-i));
+ __ vdup(Neon8, q15, r4);
+ __ ExtractLane(r5, q15, NeonS8, i);
+ __ str(r5, MemOperand(r0, offsetof(T, i8x16_high) + 4 * i));
+ }
+ }
+
+ __ ldm(ia_w, sp, r4.bit() | r5.bit() | pc.bit());
+
+ CodeDesc desc;
+ masm->GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef DEBUG
+ OFStream os(stdout);
+ code->Print(os);
+#endif
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0);
+ USE(dummy);
+ for (int i = 0; i < 4; i++) {
+ CHECK_EQ(i, t.i32x4_low[i]);
+ CHECK_EQ(i, t.f32x4_low[i]);
+ }
+ for (int i = 0; i < 8; i++) {
+ CHECK_EQ(i, t.i16x8_low[i]);
+ }
+ for (int i = 0; i < 16; i++) {
+ CHECK_EQ(i, t.i8x16_low[i]);
+ }
+ if (CpuFeatures::IsSupported(VFP32DREGS)) {
+ for (int i = 0; i < 4; i++) {
+ CHECK_EQ(-i, t.i32x4_high[i]);
+ CHECK_EQ(-i, t.f32x4_high[i]);
+ }
+ for (int i = 0; i < 8; i++) {
+ CHECK_EQ(-i, t.i16x8_high[i]);
+ }
+ for (int i = 0; i < 16; i++) {
+ CHECK_EQ(-i, t.i8x16_high[i]);
+ }
+ }
+}
+
+TEST(ReplaceLane) {
+ if (!CpuFeatures::IsSupported(NEON)) return;
+
+ // Allocate an executable page of memory.
+ size_t actual_size;
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
+ CHECK(buffer);
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope handles(isolate);
+ MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size),
+ v8::internal::CodeObjectRequired::kYes);
+ MacroAssembler* masm = &assembler; // Create a pointer for the __ macro.
+
+ typedef struct {
+ int32_t i32x4_low[4];
+ int32_t i32x4_high[4];
+ int16_t i16x8_low[8];
+ int16_t i16x8_high[8];
+ int8_t i8x16_low[16];
+ int8_t i8x16_high[16];
+ int32_t f32x4_low[4];
+ int32_t f32x4_high[4];
+ } T;
+ T t;
+
+ __ stm(db_w, sp, r4.bit() | r5.bit() | r6.bit() | r7.bit() | lr.bit());
+
+ const Register kScratch = r5;
+
+ __ veor(q0, q0, q0); // Zero
+ __ veor(q1, q1, q1); // Zero
+ for (int i = 0; i < 4; i++) {
+ __ mov(r4, Operand(i));
+ __ ReplaceLane(q0, q0, r4, NeonS32, i);
+ SwVfpRegister si = SwVfpRegister::from_code(i);
+ __ vmov(si, r4);
+ __ ReplaceLane(q1, q1, si, kScratch, i);
+ }
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, i32x4_low))));
+ __ vst1(Neon8, NeonListOperand(q0), NeonMemOperand(r4));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, f32x4_low))));
+ __ vst1(Neon8, NeonListOperand(q1), NeonMemOperand(r4));
+
+ __ veor(q0, q0, q0); // Zero
+ for (int i = 0; i < 8; i++) {
+ __ mov(r4, Operand(i));
+ __ ReplaceLane(q0, q0, r4, NeonS16, i);
+ }
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, i16x8_low))));
+ __ vst1(Neon8, NeonListOperand(q0), NeonMemOperand(r4));
+
+ __ veor(q0, q0, q0); // Zero
+ for (int i = 0; i < 16; i++) {
+ __ mov(r4, Operand(i));
+ __ ReplaceLane(q0, q0, r4, NeonS8, i);
+ }
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, i8x16_low))));
+ __ vst1(Neon8, NeonListOperand(q0), NeonMemOperand(r4));
+
+ if (CpuFeatures::IsSupported(VFP32DREGS)) {
+ __ veor(q14, q14, q14); // Zero
+ __ veor(q15, q15, q15); // Zero
+ for (int i = 0; i < 4; i++) {
+ __ mov(r4, Operand(-i));
+ __ ReplaceLane(q14, q14, r4, NeonS32, i);
+ SwVfpRegister si = SwVfpRegister::from_code(i);
+ __ vmov(si, r4);
+ __ ReplaceLane(q15, q15, si, kScratch, i);
+ }
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, i32x4_high))));
+ __ vst1(Neon8, NeonListOperand(q14), NeonMemOperand(r4));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, f32x4_high))));
+ __ vst1(Neon8, NeonListOperand(q15), NeonMemOperand(r4));
+
+ __ veor(q14, q14, q14); // Zero
+ for (int i = 0; i < 8; i++) {
+ __ mov(r4, Operand(-i));
+ __ ReplaceLane(q14, q14, r4, NeonS16, i);
+ }
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, i16x8_high))));
+ __ vst1(Neon8, NeonListOperand(q14), NeonMemOperand(r4));
+
+ __ veor(q14, q14, q14); // Zero
+ for (int i = 0; i < 16; i++) {
+ __ mov(r4, Operand(-i));
+ __ ReplaceLane(q14, q14, r4, NeonS8, i);
+ }
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, i8x16_high))));
+ __ vst1(Neon8, NeonListOperand(q14), NeonMemOperand(r4));
+ }
+
+ __ ldm(ia_w, sp, r4.bit() | r5.bit() | r6.bit() | r7.bit() | pc.bit());
+
+ CodeDesc desc;
+ masm->GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef DEBUG
+ OFStream os(stdout);
+ code->Print(os);
+#endif
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0);
+ USE(dummy);
+ for (int i = 0; i < 4; i++) {
+ CHECK_EQ(i, t.i32x4_low[i]);
+ CHECK_EQ(i, t.f32x4_low[i]);
+ }
+ for (int i = 0; i < 8; i++) {
+ CHECK_EQ(i, t.i16x8_low[i]);
+ }
+ for (int i = 0; i < 16; i++) {
+ CHECK_EQ(i, t.i8x16_low[i]);
+ }
+ if (CpuFeatures::IsSupported(VFP32DREGS)) {
+ for (int i = 0; i < 4; i++) {
+ CHECK_EQ(-i, t.i32x4_high[i]);
+ CHECK_EQ(-i, t.f32x4_high[i]);
+ }
+ for (int i = 0; i < 8; i++) {
+ CHECK_EQ(-i, t.i16x8_high[i]);
+ }
+ for (int i = 0; i < 16; i++) {
+ CHECK_EQ(-i, t.i8x16_high[i]);
+ }
+ }
+}
+
+#define CHECK_EQ_32X4(field, v0, v1, v2, v3) \
+ CHECK_EQ(v0, t.field[0]); \
+ CHECK_EQ(v1, t.field[1]); \
+ CHECK_EQ(v2, t.field[2]); \
+ CHECK_EQ(v3, t.field[3]);
+
+TEST(Swizzle) {
+ if (!CpuFeatures::IsSupported(NEON)) return;
+
+ // Allocate an executable page of memory.
+ size_t actual_size;
+ byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
+ Assembler::kMinimalBufferSize, &actual_size, true));
+ CHECK(buffer);
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope handles(isolate);
+ MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size),
+ v8::internal::CodeObjectRequired::kYes);
+ MacroAssembler* masm = &assembler; // Create a pointer for the __ macro.
+
+ typedef struct {
+ int32_t _32x4_3210[4]; // identity
+ int32_t _32x4_1032[4]; // high / low swap
+ int32_t _32x4_0000[4]; // vdup's
+ int32_t _32x4_1111[4];
+ int32_t _32x4_2222[4];
+ int32_t _32x4_3333[4];
+ int32_t _32x4_2103[4]; // rotate left
+ int32_t _32x4_0321[4]; // rotate right
+ int32_t _32x4_1132[4]; // irregular
+ int32_t _32x4_1132_in_place[4]; // irregular, in-place
+ } T;
+ T t;
+
+ __ stm(db_w, sp, r4.bit() | r5.bit() | r6.bit() | r7.bit() | lr.bit());
+
+ const Register kScratch = r5;
+
+ // Make test vector [0, 1, 2, 3]
+ __ veor(q1, q1, q1); // Zero
+ for (int i = 0; i < 4; i++) {
+ __ mov(r4, Operand(i));
+ __ ReplaceLane(q1, q1, r4, NeonS32, i);
+ }
+ __ Swizzle(q0, q1, kScratch, Neon32, 0x3210);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, _32x4_3210))));
+ __ vst1(Neon8, NeonListOperand(q0), NeonMemOperand(r4));
+
+ __ Swizzle(q0, q1, kScratch, Neon32, 0x1032);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, _32x4_1032))));
+ __ vst1(Neon8, NeonListOperand(q0), NeonMemOperand(r4));
+
+ __ Swizzle(q0, q1, kScratch, Neon32, 0x0000);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, _32x4_0000))));
+ __ vst1(Neon8, NeonListOperand(q0), NeonMemOperand(r4));
+
+ __ Swizzle(q0, q1, kScratch, Neon32, 0x1111);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, _32x4_1111))));
+ __ vst1(Neon8, NeonListOperand(q0), NeonMemOperand(r4));
+
+ __ Swizzle(q0, q1, kScratch, Neon32, 0x2222);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, _32x4_2222))));
+ __ vst1(Neon8, NeonListOperand(q0), NeonMemOperand(r4));
+
+ __ Swizzle(q0, q1, kScratch, Neon32, 0x3333);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, _32x4_3333))));
+ __ vst1(Neon8, NeonListOperand(q0), NeonMemOperand(r4));
+
+ __ Swizzle(q0, q1, kScratch, Neon32, 0x2103);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, _32x4_2103))));
+ __ vst1(Neon8, NeonListOperand(q0), NeonMemOperand(r4));
+
+ __ Swizzle(q0, q1, kScratch, Neon32, 0x0321);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, _32x4_0321))));
+ __ vst1(Neon8, NeonListOperand(q0), NeonMemOperand(r4));
+
+ __ Swizzle(q0, q1, kScratch, Neon32, 0x1132);
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, _32x4_1132))));
+ __ vst1(Neon8, NeonListOperand(q0), NeonMemOperand(r4));
+
+ __ vmov(q0, q1);
+ __ Swizzle(q0, q0, kScratch, Neon32, 0x1132);
+ __ add(r4, r0,
+ Operand(static_cast<int32_t>(offsetof(T, _32x4_1132_in_place))));
+ __ vst1(Neon8, NeonListOperand(q0), NeonMemOperand(r4));
+
+ __ ldm(ia_w, sp, r4.bit() | r5.bit() | r6.bit() | r7.bit() | pc.bit());
+
+ CodeDesc desc;
+ masm->GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef DEBUG
+ OFStream os(stdout);
+ code->Print(os);
+#endif
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0);
+ USE(dummy);
+ CHECK_EQ_32X4(_32x4_3210, 0, 1, 2, 3);
+ CHECK_EQ_32X4(_32x4_1032, 2, 3, 0, 1);
+ CHECK_EQ_32X4(_32x4_0000, 0, 0, 0, 0);
+ CHECK_EQ_32X4(_32x4_1111, 1, 1, 1, 1);
+ CHECK_EQ_32X4(_32x4_2222, 2, 2, 2, 2);
+ CHECK_EQ_32X4(_32x4_3333, 3, 3, 3, 3);
+ CHECK_EQ_32X4(_32x4_2103, 3, 0, 1, 2);
+ CHECK_EQ_32X4(_32x4_0321, 1, 2, 3, 0);
+ CHECK_EQ_32X4(_32x4_1132, 2, 3, 1, 1);
+ CHECK_EQ_32X4(_32x4_1132_in_place, 2, 3, 1, 1);
+}
+
#undef __
diff --git a/deps/v8/test/cctest/test-macro-assembler-mips.cc b/deps/v8/test/cctest/test-macro-assembler-mips.cc
index 2f3edee7da..77cdaec72a 100644
--- a/deps/v8/test/cctest/test-macro-assembler-mips.cc
+++ b/deps/v8/test/cctest/test-macro-assembler-mips.cc
@@ -41,6 +41,7 @@ using namespace v8::internal;
typedef void* (*F)(int x, int y, int p2, int p3, int p4);
typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4);
typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4);
+typedef Object* (*F4)(void* p0, void* p1, int p2, int p3, int p4);
#define __ masm->
@@ -282,6 +283,96 @@ TEST(jump_tables5) {
}
}
+TEST(jump_tables6) {
+ // Similar to test-assembler-mips jump_tables1, with extra test for branch
+ // trampoline required after emission of the dd table (where trampolines are
+ // blocked). This test checks if number of really generated instructions is
+ // greater than number of counted instructions from code, as we are expecting
+ // generation of trampoline in this case (when number of kFillInstr
+ // instructions is close to 32K)
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assembler(isolate, nullptr, 0,
+ v8::internal::CodeObjectRequired::kYes);
+ MacroAssembler* masm = &assembler;
+
+ const int kSwitchTableCases = 40;
+
+ const int kInstrSize = Assembler::kInstrSize;
+ const int kMaxBranchOffset = Assembler::kMaxBranchOffset;
+ const int kTrampolineSlotsSize = Assembler::kTrampolineSlotsSize;
+ const int kSwitchTablePrologueSize = MacroAssembler::kSwitchTablePrologueSize;
+
+ const int kMaxOffsetForTrampolineStart =
+ kMaxBranchOffset - 16 * kTrampolineSlotsSize;
+ const int kFillInstr = (kMaxOffsetForTrampolineStart / kInstrSize) -
+ (kSwitchTablePrologueSize + kSwitchTableCases) - 20;
+
+ int values[kSwitchTableCases];
+ isolate->random_number_generator()->NextBytes(values, sizeof(values));
+ Label labels[kSwitchTableCases];
+ Label near_start, end, done;
+
+ __ Push(ra);
+ __ mov(v0, zero_reg);
+
+ int offs1 = masm->pc_offset();
+ int gen_insn = 0;
+
+ __ Branch(&end);
+ gen_insn += Assembler::IsCompactBranchSupported() ? 1 : 2;
+ __ bind(&near_start);
+
+ // Generate slightly less than 32K instructions, which will soon require
+ // trampoline for branch distance fixup.
+ for (int i = 0; i < kFillInstr; ++i) {
+ __ addiu(v0, v0, 1);
+ }
+ gen_insn += kFillInstr;
+
+ __ GenerateSwitchTable(a0, kSwitchTableCases,
+ [&labels](size_t i) { return labels + i; });
+ gen_insn += (kSwitchTablePrologueSize + kSwitchTableCases);
+
+ for (int i = 0; i < kSwitchTableCases; ++i) {
+ __ bind(&labels[i]);
+ __ li(v0, values[i]);
+ __ Branch(&done);
+ }
+ gen_insn +=
+ ((Assembler::IsCompactBranchSupported() ? 3 : 4) * kSwitchTableCases);
+
+ // If offset from here to first branch instr is greater than max allowed
+ // offset for trampoline ...
+ CHECK_LT(kMaxOffsetForTrampolineStart, masm->pc_offset() - offs1);
+ // ... number of generated instructions must be greater then "gen_insn",
+ // as we are expecting trampoline generation
+ CHECK_LT(gen_insn, (masm->pc_offset() - offs1) / kInstrSize);
+
+ __ bind(&done);
+ __ Pop(ra);
+ __ jr(ra);
+ __ nop();
+
+ __ bind(&end);
+ __ Branch(&near_start);
+
+ CodeDesc desc;
+ masm->GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef OBJECT_PRINT
+ code->Print(std::cout);
+#endif
+ F1 f = FUNCTION_CAST<F1>(code->entry());
+ for (int i = 0; i < kSwitchTableCases; ++i) {
+ int res =
+ reinterpret_cast<int>(CALL_GENERATED_CODE(isolate, f, i, 0, 0, 0, 0));
+ ::printf("f(%d) = %d\n", i, res);
+ CHECK_EQ(values[i], res);
+ }
+}
static uint32_t run_lsa(uint32_t rt, uint32_t rs, int8_t sa) {
Isolate* isolate = CcTest::i_isolate();
@@ -439,11 +530,11 @@ TEST(cvt_s_w_Trunc_uw_s) {
CcTest::InitializeVM();
FOR_UINT32_INPUTS(i, cvt_trunc_uint32_test_values) {
uint32_t input = *i;
- CHECK_EQ(static_cast<float>(input),
- run_Cvt<uint32_t>(input, [](MacroAssembler* masm) {
- __ cvt_s_w(f0, f4);
- __ Trunc_uw_s(f2, f0, f1);
- }));
+ auto fn = [](MacroAssembler* masm) {
+ __ cvt_s_w(f0, f4);
+ __ Trunc_uw_s(f2, f0, f6);
+ };
+ CHECK_EQ(static_cast<float>(input), run_Cvt<uint32_t>(input, fn));
}
}
@@ -451,11 +542,11 @@ TEST(cvt_d_w_Trunc_w_d) {
CcTest::InitializeVM();
FOR_INT32_INPUTS(i, cvt_trunc_int32_test_values) {
int32_t input = *i;
- CHECK_EQ(static_cast<double>(input),
- run_Cvt<int32_t>(input, [](MacroAssembler* masm) {
- __ cvt_d_w(f0, f4);
- __ Trunc_w_d(f2, f0);
- }));
+ auto fn = [](MacroAssembler* masm) {
+ __ cvt_d_w(f0, f4);
+ __ Trunc_w_d(f2, f0);
+ };
+ CHECK_EQ(static_cast<double>(input), run_Cvt<int32_t>(input, fn));
}
}
@@ -937,13 +1028,13 @@ TEST(min_max_nan) {
__ ldc1(f8, MemOperand(a0, offsetof(TestFloat, b)));
__ lwc1(f2, MemOperand(a0, offsetof(TestFloat, e)));
__ lwc1(f6, MemOperand(a0, offsetof(TestFloat, f)));
- __ MinNaNCheck_d(f10, f4, f8, &handle_mind_nan);
+ __ Float64Min(f10, f4, f8, &handle_mind_nan);
__ bind(&back_mind_nan);
- __ MaxNaNCheck_d(f12, f4, f8, &handle_maxd_nan);
+ __ Float64Max(f12, f4, f8, &handle_maxd_nan);
__ bind(&back_maxd_nan);
- __ MinNaNCheck_s(f14, f2, f6, &handle_mins_nan);
+ __ Float32Min(f14, f2, f6, &handle_mins_nan);
__ bind(&back_mins_nan);
- __ MaxNaNCheck_s(f16, f2, f6, &handle_maxs_nan);
+ __ Float32Max(f16, f2, f6, &handle_maxs_nan);
__ bind(&back_maxs_nan);
__ sdc1(f10, MemOperand(a0, offsetof(TestFloat, c)));
__ sdc1(f12, MemOperand(a0, offsetof(TestFloat, d)));
@@ -1041,36 +1132,39 @@ TEST(Ulh) {
int32_t in_offset = *j1 + *k1;
int32_t out_offset = *j2 + *k2;
- CHECK_EQ(true, run_Unaligned<uint16_t>(
- buffer_middle, in_offset, out_offset, value,
- [](MacroAssembler* masm, int32_t in_offset,
- int32_t out_offset) {
- __ Ulh(v0, MemOperand(a0, in_offset));
- __ Ush(v0, MemOperand(a0, out_offset), v0);
- }));
- CHECK_EQ(true, run_Unaligned<uint16_t>(
- buffer_middle, in_offset, out_offset, value,
- [](MacroAssembler* masm, int32_t in_offset,
- int32_t out_offset) {
- __ mov(t0, a0);
- __ Ulh(a0, MemOperand(a0, in_offset));
- __ Ush(a0, MemOperand(t0, out_offset), v0);
- }));
- CHECK_EQ(true, run_Unaligned<uint16_t>(
- buffer_middle, in_offset, out_offset, value,
- [](MacroAssembler* masm, int32_t in_offset,
- int32_t out_offset) {
- __ mov(t0, a0);
- __ Ulhu(a0, MemOperand(a0, in_offset));
- __ Ush(a0, MemOperand(t0, out_offset), t1);
- }));
- CHECK_EQ(true, run_Unaligned<uint16_t>(
- buffer_middle, in_offset, out_offset, value,
- [](MacroAssembler* masm, int32_t in_offset,
- int32_t out_offset) {
- __ Ulhu(v0, MemOperand(a0, in_offset));
- __ Ush(v0, MemOperand(a0, out_offset), t1);
- }));
+ auto fn_1 = [](MacroAssembler* masm, int32_t in_offset,
+ int32_t out_offset) {
+ __ Ulh(v0, MemOperand(a0, in_offset));
+ __ Ush(v0, MemOperand(a0, out_offset), v0);
+ };
+ CHECK_EQ(true, run_Unaligned<uint16_t>(buffer_middle, in_offset,
+ out_offset, value, fn_1));
+
+ auto fn_2 = [](MacroAssembler* masm, int32_t in_offset,
+ int32_t out_offset) {
+ __ mov(t0, a0);
+ __ Ulh(a0, MemOperand(a0, in_offset));
+ __ Ush(a0, MemOperand(t0, out_offset), v0);
+ };
+ CHECK_EQ(true, run_Unaligned<uint16_t>(buffer_middle, in_offset,
+ out_offset, value, fn_2));
+
+ auto fn_3 = [](MacroAssembler* masm, int32_t in_offset,
+ int32_t out_offset) {
+ __ mov(t0, a0);
+ __ Ulhu(a0, MemOperand(a0, in_offset));
+ __ Ush(a0, MemOperand(t0, out_offset), t1);
+ };
+ CHECK_EQ(true, run_Unaligned<uint16_t>(buffer_middle, in_offset,
+ out_offset, value, fn_3));
+
+ auto fn_4 = [](MacroAssembler* masm, int32_t in_offset,
+ int32_t out_offset) {
+ __ Ulhu(v0, MemOperand(a0, in_offset));
+ __ Ush(v0, MemOperand(a0, out_offset), t1);
+ };
+ CHECK_EQ(true, run_Unaligned<uint16_t>(buffer_middle, in_offset,
+ out_offset, value, fn_4));
}
}
}
@@ -1090,39 +1184,39 @@ TEST(Ulh_bitextension) {
int32_t in_offset = *j1 + *k1;
int32_t out_offset = *j2 + *k2;
- CHECK_EQ(true, run_Unaligned<uint16_t>(
- buffer_middle, in_offset, out_offset, value,
- [](MacroAssembler* masm, int32_t in_offset,
- int32_t out_offset) {
- Label success, fail, end, different;
- __ Ulh(t0, MemOperand(a0, in_offset));
- __ Ulhu(t1, MemOperand(a0, in_offset));
- __ Branch(&different, ne, t0, Operand(t1));
-
- // If signed and unsigned values are same, check
- // the upper bits to see if they are zero
- __ sra(t0, t0, 15);
- __ Branch(&success, eq, t0, Operand(zero_reg));
- __ Branch(&fail);
-
- // If signed and unsigned values are different,
- // check that the upper bits are complementary
- __ bind(&different);
- __ sra(t1, t1, 15);
- __ Branch(&fail, ne, t1, Operand(1));
- __ sra(t0, t0, 15);
- __ addiu(t0, t0, 1);
- __ Branch(&fail, ne, t0, Operand(zero_reg));
- // Fall through to success
-
- __ bind(&success);
- __ Ulh(t0, MemOperand(a0, in_offset));
- __ Ush(t0, MemOperand(a0, out_offset), v0);
- __ Branch(&end);
- __ bind(&fail);
- __ Ush(zero_reg, MemOperand(a0, out_offset), v0);
- __ bind(&end);
- }));
+ auto fn = [](MacroAssembler* masm, int32_t in_offset,
+ int32_t out_offset) {
+ Label success, fail, end, different;
+ __ Ulh(t0, MemOperand(a0, in_offset));
+ __ Ulhu(t1, MemOperand(a0, in_offset));
+ __ Branch(&different, ne, t0, Operand(t1));
+
+ // If signed and unsigned values are same, check
+ // the upper bits to see if they are zero
+ __ sra(t0, t0, 15);
+ __ Branch(&success, eq, t0, Operand(zero_reg));
+ __ Branch(&fail);
+
+ // If signed and unsigned values are different,
+ // check that the upper bits are complementary
+ __ bind(&different);
+ __ sra(t1, t1, 15);
+ __ Branch(&fail, ne, t1, Operand(1));
+ __ sra(t0, t0, 15);
+ __ addiu(t0, t0, 1);
+ __ Branch(&fail, ne, t0, Operand(zero_reg));
+ // Fall through to success
+
+ __ bind(&success);
+ __ Ulh(t0, MemOperand(a0, in_offset));
+ __ Ush(t0, MemOperand(a0, out_offset), v0);
+ __ Branch(&end);
+ __ bind(&fail);
+ __ Ush(zero_reg, MemOperand(a0, out_offset), v0);
+ __ bind(&end);
+ };
+ CHECK_EQ(true, run_Unaligned<uint16_t>(buffer_middle, in_offset,
+ out_offset, value, fn));
}
}
}
@@ -1142,22 +1236,23 @@ TEST(Ulw) {
int32_t in_offset = *j1 + *k1;
int32_t out_offset = *j2 + *k2;
- CHECK_EQ(true, run_Unaligned<uint32_t>(
- buffer_middle, in_offset, out_offset, value,
- [](MacroAssembler* masm, int32_t in_offset,
- int32_t out_offset) {
- __ Ulw(v0, MemOperand(a0, in_offset));
- __ Usw(v0, MemOperand(a0, out_offset));
- }));
+ auto fn_1 = [](MacroAssembler* masm, int32_t in_offset,
+ int32_t out_offset) {
+ __ Ulw(v0, MemOperand(a0, in_offset));
+ __ Usw(v0, MemOperand(a0, out_offset));
+ };
+ CHECK_EQ(true, run_Unaligned<uint32_t>(buffer_middle, in_offset,
+ out_offset, value, fn_1));
+
+ auto fn_2 = [](MacroAssembler* masm, int32_t in_offset,
+ int32_t out_offset) {
+ __ mov(t0, a0);
+ __ Ulw(a0, MemOperand(a0, in_offset));
+ __ Usw(a0, MemOperand(t0, out_offset));
+ };
CHECK_EQ(true,
- run_Unaligned<uint32_t>(
- buffer_middle, in_offset, out_offset, (uint32_t)value,
- [](MacroAssembler* masm, int32_t in_offset,
- int32_t out_offset) {
- __ mov(t0, a0);
- __ Ulw(a0, MemOperand(a0, in_offset));
- __ Usw(a0, MemOperand(t0, out_offset));
- }));
+ run_Unaligned<uint32_t>(buffer_middle, in_offset, out_offset,
+ (uint32_t)value, fn_2));
}
}
}
@@ -1177,13 +1272,13 @@ TEST(Ulwc1) {
int32_t in_offset = *j1 + *k1;
int32_t out_offset = *j2 + *k2;
- CHECK_EQ(true, run_Unaligned<float>(
- buffer_middle, in_offset, out_offset, value,
- [](MacroAssembler* masm, int32_t in_offset,
- int32_t out_offset) {
- __ Ulwc1(f0, MemOperand(a0, in_offset), t0);
- __ Uswc1(f0, MemOperand(a0, out_offset), t0);
- }));
+ auto fn = [](MacroAssembler* masm, int32_t in_offset,
+ int32_t out_offset) {
+ __ Ulwc1(f0, MemOperand(a0, in_offset), t0);
+ __ Uswc1(f0, MemOperand(a0, out_offset), t0);
+ };
+ CHECK_EQ(true, run_Unaligned<float>(buffer_middle, in_offset,
+ out_offset, value, fn));
}
}
}
@@ -1203,13 +1298,13 @@ TEST(Uldc1) {
int32_t in_offset = *j1 + *k1;
int32_t out_offset = *j2 + *k2;
- CHECK_EQ(true, run_Unaligned<double>(
- buffer_middle, in_offset, out_offset, value,
- [](MacroAssembler* masm, int32_t in_offset,
- int32_t out_offset) {
- __ Uldc1(f0, MemOperand(a0, in_offset), t0);
- __ Usdc1(f0, MemOperand(a0, out_offset), t0);
- }));
+ auto fn = [](MacroAssembler* masm, int32_t in_offset,
+ int32_t out_offset) {
+ __ Uldc1(f0, MemOperand(a0, in_offset), t0);
+ __ Usdc1(f0, MemOperand(a0, out_offset), t0);
+ };
+ CHECK_EQ(true, run_Unaligned<double>(buffer_middle, in_offset,
+ out_offset, value, fn));
}
}
}
@@ -1257,15 +1352,303 @@ TEST(Sltu) {
uint32_t rs = *i;
uint32_t rd = *j;
- CHECK_EQ(rs < rd, run_Sltu(rs, rd,
- [](MacroAssembler* masm, uint32_t imm) {
- __ Sltu(v0, a0, Operand(imm));
- }));
- CHECK_EQ(rs < rd,
- run_Sltu(rs, rd, [](MacroAssembler* masm,
- uint32_t imm) { __ Sltu(v0, a0, a1); }));
+ auto fn_1 = [](MacroAssembler* masm, uint32_t imm) {
+ __ Sltu(v0, a0, Operand(imm));
+ };
+ CHECK_EQ(rs < rd, run_Sltu(rs, rd, fn_1));
+
+ auto fn_2 = [](MacroAssembler* masm, uint32_t imm) {
+ __ Sltu(v0, a0, a1);
+ };
+ CHECK_EQ(rs < rd, run_Sltu(rs, rd, fn_2));
}
}
}
+template <typename T, typename Inputs, typename Results>
+static ::F4 GenerateMacroFloat32MinMax(MacroAssembler* masm) {
+ T a = T::from_code(4); // f4
+ T b = T::from_code(6); // f6
+ T c = T::from_code(8); // f8
+
+ Label ool_min_abc, ool_min_aab, ool_min_aba;
+ Label ool_max_abc, ool_max_aab, ool_max_aba;
+
+ Label done_min_abc, done_min_aab, done_min_aba;
+ Label done_max_abc, done_max_aab, done_max_aba;
+
+#define FLOAT_MIN_MAX(fminmax, res, x, y, done, ool, res_field) \
+ __ lwc1(x, MemOperand(a0, offsetof(Inputs, src1_))); \
+ __ lwc1(y, MemOperand(a0, offsetof(Inputs, src2_))); \
+ __ fminmax(res, x, y, &ool); \
+ __ bind(&done); \
+ __ swc1(a, MemOperand(a1, offsetof(Results, res_field)))
+
+ // a = min(b, c);
+ FLOAT_MIN_MAX(Float32Min, a, b, c, done_min_abc, ool_min_abc, min_abc_);
+ // a = min(a, b);
+ FLOAT_MIN_MAX(Float32Min, a, a, b, done_min_aab, ool_min_aab, min_aab_);
+ // a = min(b, a);
+ FLOAT_MIN_MAX(Float32Min, a, b, a, done_min_aba, ool_min_aba, min_aba_);
+
+ // a = max(b, c);
+ FLOAT_MIN_MAX(Float32Max, a, b, c, done_max_abc, ool_max_abc, max_abc_);
+ // a = max(a, b);
+ FLOAT_MIN_MAX(Float32Max, a, a, b, done_max_aab, ool_max_aab, max_aab_);
+ // a = max(b, a);
+ FLOAT_MIN_MAX(Float32Max, a, b, a, done_max_aba, ool_max_aba, max_aba_);
+
+#undef FLOAT_MIN_MAX
+
+ __ jr(ra);
+ __ nop();
+
+ // Generate out-of-line cases.
+ __ bind(&ool_min_abc);
+ __ Float32MinOutOfLine(a, b, c);
+ __ Branch(&done_min_abc);
+
+ __ bind(&ool_min_aab);
+ __ Float32MinOutOfLine(a, a, b);
+ __ Branch(&done_min_aab);
+
+ __ bind(&ool_min_aba);
+ __ Float32MinOutOfLine(a, b, a);
+ __ Branch(&done_min_aba);
+
+ __ bind(&ool_max_abc);
+ __ Float32MaxOutOfLine(a, b, c);
+ __ Branch(&done_max_abc);
+
+ __ bind(&ool_max_aab);
+ __ Float32MaxOutOfLine(a, a, b);
+ __ Branch(&done_max_aab);
+
+ __ bind(&ool_max_aba);
+ __ Float32MaxOutOfLine(a, b, a);
+ __ Branch(&done_max_aba);
+
+ CodeDesc desc;
+ masm->GetCode(&desc);
+ Handle<Code> code = masm->isolate()->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef DEBUG
+ OFStream os(stdout);
+ code->Print(os);
+#endif
+ return FUNCTION_CAST<::F4>(code->entry());
+}
+
+TEST(macro_float_minmax_f32) {
+ // Test the Float32Min and Float32Max macros.
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assembler(isolate, NULL, 0,
+ v8::internal::CodeObjectRequired::kYes);
+ MacroAssembler* masm = &assembler;
+
+ struct Inputs {
+ float src1_;
+ float src2_;
+ };
+
+ struct Results {
+ // Check all register aliasing possibilities in order to exercise all
+ // code-paths in the macro assembler.
+ float min_abc_;
+ float min_aab_;
+ float min_aba_;
+ float max_abc_;
+ float max_aab_;
+ float max_aba_;
+ };
+
+ ::F4 f = GenerateMacroFloat32MinMax<FPURegister, Inputs, Results>(masm);
+ Object* dummy = nullptr;
+ USE(dummy);
+
+#define CHECK_MINMAX(src1, src2, min, max) \
+ do { \
+ Inputs inputs = {src1, src2}; \
+ Results results; \
+ dummy = CALL_GENERATED_CODE(isolate, f, &inputs, &results, 0, 0, 0); \
+ CHECK_EQ(bit_cast<uint32_t>(min), bit_cast<uint32_t>(results.min_abc_)); \
+ CHECK_EQ(bit_cast<uint32_t>(min), bit_cast<uint32_t>(results.min_aab_)); \
+ CHECK_EQ(bit_cast<uint32_t>(min), bit_cast<uint32_t>(results.min_aba_)); \
+ CHECK_EQ(bit_cast<uint32_t>(max), bit_cast<uint32_t>(results.max_abc_)); \
+ CHECK_EQ(bit_cast<uint32_t>(max), bit_cast<uint32_t>(results.max_aab_)); \
+ CHECK_EQ(bit_cast<uint32_t>(max), bit_cast<uint32_t>(results.max_aba_)); \
+ /* Use a bit_cast to correctly identify -0.0 and NaNs. */ \
+ } while (0)
+
+ float nan_a = std::numeric_limits<float>::quiet_NaN();
+ float nan_b = std::numeric_limits<float>::quiet_NaN();
+
+ CHECK_MINMAX(1.0f, -1.0f, -1.0f, 1.0f);
+ CHECK_MINMAX(-1.0f, 1.0f, -1.0f, 1.0f);
+ CHECK_MINMAX(0.0f, -1.0f, -1.0f, 0.0f);
+ CHECK_MINMAX(-1.0f, 0.0f, -1.0f, 0.0f);
+ CHECK_MINMAX(-0.0f, -1.0f, -1.0f, -0.0f);
+ CHECK_MINMAX(-1.0f, -0.0f, -1.0f, -0.0f);
+ CHECK_MINMAX(0.0f, 1.0f, 0.0f, 1.0f);
+ CHECK_MINMAX(1.0f, 0.0f, 0.0f, 1.0f);
+
+ CHECK_MINMAX(0.0f, 0.0f, 0.0f, 0.0f);
+ CHECK_MINMAX(-0.0f, -0.0f, -0.0f, -0.0f);
+ CHECK_MINMAX(-0.0f, 0.0f, -0.0f, 0.0f);
+ CHECK_MINMAX(0.0f, -0.0f, -0.0f, 0.0f);
+
+ CHECK_MINMAX(0.0f, nan_a, nan_a, nan_a);
+ CHECK_MINMAX(nan_a, 0.0f, nan_a, nan_a);
+ CHECK_MINMAX(nan_a, nan_b, nan_a, nan_a);
+ CHECK_MINMAX(nan_b, nan_a, nan_b, nan_b);
+
+#undef CHECK_MINMAX
+}
+
+template <typename T, typename Inputs, typename Results>
+static ::F4 GenerateMacroFloat64MinMax(MacroAssembler* masm) {
+ T a = T::from_code(4); // f4
+ T b = T::from_code(6); // f6
+ T c = T::from_code(8); // f8
+
+ Label ool_min_abc, ool_min_aab, ool_min_aba;
+ Label ool_max_abc, ool_max_aab, ool_max_aba;
+
+ Label done_min_abc, done_min_aab, done_min_aba;
+ Label done_max_abc, done_max_aab, done_max_aba;
+
+#define FLOAT_MIN_MAX(fminmax, res, x, y, done, ool, res_field) \
+ __ ldc1(x, MemOperand(a0, offsetof(Inputs, src1_))); \
+ __ ldc1(y, MemOperand(a0, offsetof(Inputs, src2_))); \
+ __ fminmax(res, x, y, &ool); \
+ __ bind(&done); \
+ __ sdc1(a, MemOperand(a1, offsetof(Results, res_field)))
+
+ // a = min(b, c);
+ FLOAT_MIN_MAX(Float64Min, a, b, c, done_min_abc, ool_min_abc, min_abc_);
+ // a = min(a, b);
+ FLOAT_MIN_MAX(Float64Min, a, a, b, done_min_aab, ool_min_aab, min_aab_);
+ // a = min(b, a);
+ FLOAT_MIN_MAX(Float64Min, a, b, a, done_min_aba, ool_min_aba, min_aba_);
+
+ // a = max(b, c);
+ FLOAT_MIN_MAX(Float64Max, a, b, c, done_max_abc, ool_max_abc, max_abc_);
+ // a = max(a, b);
+ FLOAT_MIN_MAX(Float64Max, a, a, b, done_max_aab, ool_max_aab, max_aab_);
+ // a = max(b, a);
+ FLOAT_MIN_MAX(Float64Max, a, b, a, done_max_aba, ool_max_aba, max_aba_);
+
+#undef FLOAT_MIN_MAX
+
+ __ jr(ra);
+ __ nop();
+
+ // Generate out-of-line cases.
+ __ bind(&ool_min_abc);
+ __ Float64MinOutOfLine(a, b, c);
+ __ Branch(&done_min_abc);
+
+ __ bind(&ool_min_aab);
+ __ Float64MinOutOfLine(a, a, b);
+ __ Branch(&done_min_aab);
+
+ __ bind(&ool_min_aba);
+ __ Float64MinOutOfLine(a, b, a);
+ __ Branch(&done_min_aba);
+
+ __ bind(&ool_max_abc);
+ __ Float64MaxOutOfLine(a, b, c);
+ __ Branch(&done_max_abc);
+
+ __ bind(&ool_max_aab);
+ __ Float64MaxOutOfLine(a, a, b);
+ __ Branch(&done_max_aab);
+
+ __ bind(&ool_max_aba);
+ __ Float64MaxOutOfLine(a, b, a);
+ __ Branch(&done_max_aba);
+
+ CodeDesc desc;
+ masm->GetCode(&desc);
+ Handle<Code> code = masm->isolate()->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef DEBUG
+ OFStream os(stdout);
+ code->Print(os);
+#endif
+ return FUNCTION_CAST<::F4>(code->entry());
+}
+
+TEST(macro_float_minmax_f64) {
+ // Test the Float64Min and Float64Max macros.
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assembler(isolate, NULL, 0,
+ v8::internal::CodeObjectRequired::kYes);
+ MacroAssembler* masm = &assembler;
+
+ struct Inputs {
+ double src1_;
+ double src2_;
+ };
+
+ struct Results {
+ // Check all register aliasing possibilities in order to exercise all
+ // code-paths in the macro assembler.
+ double min_abc_;
+ double min_aab_;
+ double min_aba_;
+ double max_abc_;
+ double max_aab_;
+ double max_aba_;
+ };
+
+ ::F4 f = GenerateMacroFloat64MinMax<DoubleRegister, Inputs, Results>(masm);
+ Object* dummy = nullptr;
+ USE(dummy);
+
+#define CHECK_MINMAX(src1, src2, min, max) \
+ do { \
+ Inputs inputs = {src1, src2}; \
+ Results results; \
+ dummy = CALL_GENERATED_CODE(isolate, f, &inputs, &results, 0, 0, 0); \
+ CHECK_EQ(bit_cast<uint64_t>(min), bit_cast<uint64_t>(results.min_abc_)); \
+ CHECK_EQ(bit_cast<uint64_t>(min), bit_cast<uint64_t>(results.min_aab_)); \
+ CHECK_EQ(bit_cast<uint64_t>(min), bit_cast<uint64_t>(results.min_aba_)); \
+ CHECK_EQ(bit_cast<uint64_t>(max), bit_cast<uint64_t>(results.max_abc_)); \
+ CHECK_EQ(bit_cast<uint64_t>(max), bit_cast<uint64_t>(results.max_aab_)); \
+ CHECK_EQ(bit_cast<uint64_t>(max), bit_cast<uint64_t>(results.max_aba_)); \
+ /* Use a bit_cast to correctly identify -0.0 and NaNs. */ \
+ } while (0)
+
+ double nan_a = std::numeric_limits<double>::quiet_NaN();
+ double nan_b = std::numeric_limits<double>::quiet_NaN();
+
+ CHECK_MINMAX(1.0, -1.0, -1.0, 1.0);
+ CHECK_MINMAX(-1.0, 1.0, -1.0, 1.0);
+ CHECK_MINMAX(0.0, -1.0, -1.0, 0.0);
+ CHECK_MINMAX(-1.0, 0.0, -1.0, 0.0);
+ CHECK_MINMAX(-0.0, -1.0, -1.0, -0.0);
+ CHECK_MINMAX(-1.0, -0.0, -1.0, -0.0);
+ CHECK_MINMAX(0.0, 1.0, 0.0, 1.0);
+ CHECK_MINMAX(1.0, 0.0, 0.0, 1.0);
+
+ CHECK_MINMAX(0.0, 0.0, 0.0, 0.0);
+ CHECK_MINMAX(-0.0, -0.0, -0.0, -0.0);
+ CHECK_MINMAX(-0.0, 0.0, -0.0, 0.0);
+ CHECK_MINMAX(0.0, -0.0, -0.0, 0.0);
+
+ CHECK_MINMAX(0.0, nan_a, nan_a, nan_a);
+ CHECK_MINMAX(nan_a, 0.0, nan_a, nan_a);
+ CHECK_MINMAX(nan_a, nan_b, nan_a, nan_a);
+ CHECK_MINMAX(nan_b, nan_a, nan_b, nan_b);
+
+#undef CHECK_MINMAX
+}
+
#undef __
diff --git a/deps/v8/test/cctest/test-macro-assembler-mips64.cc b/deps/v8/test/cctest/test-macro-assembler-mips64.cc
index 04811f6af5..cfcdeb2d40 100644
--- a/deps/v8/test/cctest/test-macro-assembler-mips64.cc
+++ b/deps/v8/test/cctest/test-macro-assembler-mips64.cc
@@ -42,6 +42,7 @@ using namespace v8::internal;
typedef void* (*F)(int64_t x, int64_t y, int p2, int p3, int p4);
typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4);
typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4);
+typedef Object* (*F4)(void* p0, void* p1, int p2, int p3, int p4);
#define __ masm->
@@ -350,6 +351,97 @@ TEST(jump_tables5) {
}
}
+TEST(jump_tables6) {
+ // Similar to test-assembler-mips jump_tables1, with extra test for branch
+ // trampoline required after emission of the dd table (where trampolines are
+ // blocked). This test checks if number of really generated instructions is
+ // greater than number of counted instructions from code, as we are expecting
+ // generation of trampoline in this case (when number of kFillInstr
+ // instructions is close to 32K)
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assembler(isolate, nullptr, 0,
+ v8::internal::CodeObjectRequired::kYes);
+ MacroAssembler* masm = &assembler;
+
+ const int kSwitchTableCases = 40;
+
+ const int kInstrSize = Assembler::kInstrSize;
+ const int kMaxBranchOffset = Assembler::kMaxBranchOffset;
+ const int kTrampolineSlotsSize = Assembler::kTrampolineSlotsSize;
+ const int kSwitchTablePrologueSize = MacroAssembler::kSwitchTablePrologueSize;
+
+ const int kMaxOffsetForTrampolineStart =
+ kMaxBranchOffset - 16 * kTrampolineSlotsSize;
+ const int kFillInstr = (kMaxOffsetForTrampolineStart / kInstrSize) -
+ (kSwitchTablePrologueSize + 2 * kSwitchTableCases) -
+ 20;
+
+ int values[kSwitchTableCases];
+ isolate->random_number_generator()->NextBytes(values, sizeof(values));
+ Label labels[kSwitchTableCases];
+ Label near_start, end, done;
+
+ __ Push(ra);
+ __ mov(v0, zero_reg);
+
+ int offs1 = masm->pc_offset();
+ int gen_insn = 0;
+
+ __ Branch(&end);
+ gen_insn += Assembler::IsCompactBranchSupported() ? 1 : 2;
+ __ bind(&near_start);
+
+ // Generate slightly less than 32K instructions, which will soon require
+ // trampoline for branch distance fixup.
+ for (int i = 0; i < kFillInstr; ++i) {
+ __ addiu(v0, v0, 1);
+ }
+ gen_insn += kFillInstr;
+
+ __ GenerateSwitchTable(a0, kSwitchTableCases,
+ [&labels](size_t i) { return labels + i; });
+ gen_insn += (kSwitchTablePrologueSize + 2 * kSwitchTableCases);
+
+ for (int i = 0; i < kSwitchTableCases; ++i) {
+ __ bind(&labels[i]);
+ __ li(v0, values[i]);
+ __ Branch(&done);
+ }
+ gen_insn +=
+ ((Assembler::IsCompactBranchSupported() ? 3 : 4) * kSwitchTableCases);
+
+ // If offset from here to first branch instr is greater than max allowed
+ // offset for trampoline ...
+ CHECK_LT(kMaxOffsetForTrampolineStart, masm->pc_offset() - offs1);
+ // ... number of generated instructions must be greater then "gen_insn",
+ // as we are expecting trampoline generation
+ CHECK_LT(gen_insn, (masm->pc_offset() - offs1) / kInstrSize);
+
+ __ bind(&done);
+ __ Pop(ra);
+ __ jr(ra);
+ __ nop();
+
+ __ bind(&end);
+ __ Branch(&near_start);
+
+ CodeDesc desc;
+ masm->GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef OBJECT_PRINT
+ code->Print(std::cout);
+#endif
+ F1 f = FUNCTION_CAST<F1>(code->entry());
+ for (int i = 0; i < kSwitchTableCases; ++i) {
+ int64_t res = reinterpret_cast<int64_t>(
+ CALL_GENERATED_CODE(isolate, f, i, 0, 0, 0, 0));
+ ::printf("f(%d) = %" PRId64 "\n", i, res);
+ CHECK_EQ(values[i], res);
+ }
+}
static uint64_t run_lsa(uint32_t rt, uint32_t rs, int8_t sa) {
Isolate* isolate = CcTest::i_isolate();
@@ -611,12 +703,12 @@ TEST(Cvt_s_uw_Trunc_uw_s) {
CcTest::InitializeVM();
FOR_UINT32_INPUTS(i, cvt_trunc_uint32_test_values) {
uint32_t input = *i;
- CHECK_EQ(static_cast<float>(input),
- run_Cvt<uint64_t>(input, [](MacroAssembler* masm) {
- __ Cvt_s_uw(f0, a0);
- __ mthc1(zero_reg, f2);
- __ Trunc_uw_s(f2, f0, f1);
- }));
+ auto fn = [](MacroAssembler* masm) {
+ __ Cvt_s_uw(f0, a0);
+ __ mthc1(zero_reg, f2);
+ __ Trunc_uw_s(f2, f0, f1);
+ };
+ CHECK_EQ(static_cast<float>(input), run_Cvt<uint64_t>(input, fn));
}
}
@@ -624,11 +716,11 @@ TEST(Cvt_s_ul_Trunc_ul_s) {
CcTest::InitializeVM();
FOR_UINT64_INPUTS(i, cvt_trunc_uint64_test_values) {
uint64_t input = *i;
- CHECK_EQ(static_cast<float>(input),
- run_Cvt<uint64_t>(input, [](MacroAssembler* masm) {
- __ Cvt_s_ul(f0, a0);
- __ Trunc_ul_s(f2, f0, f1, v0);
- }));
+ auto fn = [](MacroAssembler* masm) {
+ __ Cvt_s_ul(f0, a0);
+ __ Trunc_ul_s(f2, f0, f1, v0);
+ };
+ CHECK_EQ(static_cast<float>(input), run_Cvt<uint64_t>(input, fn));
}
}
@@ -636,11 +728,11 @@ TEST(Cvt_d_ul_Trunc_ul_d) {
CcTest::InitializeVM();
FOR_UINT64_INPUTS(i, cvt_trunc_uint64_test_values) {
uint64_t input = *i;
- CHECK_EQ(static_cast<double>(input),
- run_Cvt<uint64_t>(input, [](MacroAssembler* masm) {
- __ Cvt_d_ul(f0, a0);
- __ Trunc_ul_d(f2, f0, f1, v0);
- }));
+ auto fn = [](MacroAssembler* masm) {
+ __ Cvt_d_ul(f0, a0);
+ __ Trunc_ul_d(f2, f0, f1, v0);
+ };
+ CHECK_EQ(static_cast<double>(input), run_Cvt<uint64_t>(input, fn));
}
}
@@ -648,12 +740,12 @@ TEST(cvt_d_l_Trunc_l_d) {
CcTest::InitializeVM();
FOR_INT64_INPUTS(i, cvt_trunc_int64_test_values) {
int64_t input = *i;
- CHECK_EQ(static_cast<double>(input),
- run_Cvt<int64_t>(input, [](MacroAssembler* masm) {
- __ dmtc1(a0, f4);
- __ cvt_d_l(f0, f4);
- __ Trunc_l_d(f2, f0);
- }));
+ auto fn = [](MacroAssembler* masm) {
+ __ dmtc1(a0, f4);
+ __ cvt_d_l(f0, f4);
+ __ Trunc_l_d(f2, f0);
+ };
+ CHECK_EQ(static_cast<double>(input), run_Cvt<int64_t>(input, fn));
}
}
@@ -662,12 +754,12 @@ TEST(cvt_d_l_Trunc_l_ud) {
FOR_INT64_INPUTS(i, cvt_trunc_int64_test_values) {
int64_t input = *i;
uint64_t abs_input = (input < 0) ? -input : input;
- CHECK_EQ(static_cast<double>(abs_input),
- run_Cvt<uint64_t>(input, [](MacroAssembler* masm) {
- __ dmtc1(a0, f4);
- __ cvt_d_l(f0, f4);
- __ Trunc_l_ud(f2, f0, f6);
- }));
+ auto fn = [](MacroAssembler* masm) {
+ __ dmtc1(a0, f4);
+ __ cvt_d_l(f0, f4);
+ __ Trunc_l_ud(f2, f0, f6);
+ };
+ CHECK_EQ(static_cast<double>(abs_input), run_Cvt<uint64_t>(input, fn));
}
}
@@ -675,14 +767,14 @@ TEST(cvt_d_w_Trunc_w_d) {
CcTest::InitializeVM();
FOR_INT32_INPUTS(i, cvt_trunc_int32_test_values) {
int32_t input = *i;
- CHECK_EQ(static_cast<double>(input),
- run_Cvt<int64_t>(input, [](MacroAssembler* masm) {
- __ mtc1(a0, f4);
- __ cvt_d_w(f0, f4);
- __ Trunc_w_d(f2, f0);
- __ mfc1(v1, f2);
- __ dmtc1(v1, f2);
- }));
+ auto fn = [](MacroAssembler* masm) {
+ __ mtc1(a0, f4);
+ __ cvt_d_w(f0, f4);
+ __ Trunc_w_d(f2, f0);
+ __ mfc1(v1, f2);
+ __ dmtc1(v1, f2);
+ };
+ CHECK_EQ(static_cast<double>(input), run_Cvt<int64_t>(input, fn));
}
}
@@ -1429,13 +1521,13 @@ TEST(min_max_nan) {
__ ldc1(f8, MemOperand(a0, offsetof(TestFloat, b)));
__ lwc1(f2, MemOperand(a0, offsetof(TestFloat, e)));
__ lwc1(f6, MemOperand(a0, offsetof(TestFloat, f)));
- __ MinNaNCheck_d(f10, f4, f8, &handle_mind_nan);
+ __ Float64Min(f10, f4, f8, &handle_mind_nan);
__ bind(&back_mind_nan);
- __ MaxNaNCheck_d(f12, f4, f8, &handle_maxd_nan);
+ __ Float64Max(f12, f4, f8, &handle_maxd_nan);
__ bind(&back_maxd_nan);
- __ MinNaNCheck_s(f14, f2, f6, &handle_mins_nan);
+ __ Float32Min(f14, f2, f6, &handle_mins_nan);
__ bind(&back_mins_nan);
- __ MaxNaNCheck_s(f16, f2, f6, &handle_maxs_nan);
+ __ Float32Max(f16, f2, f6, &handle_maxs_nan);
__ bind(&back_maxs_nan);
__ sdc1(f10, MemOperand(a0, offsetof(TestFloat, c)));
__ sdc1(f12, MemOperand(a0, offsetof(TestFloat, d)));
@@ -1533,36 +1625,39 @@ TEST(Ulh) {
int32_t in_offset = *j1 + *k1;
int32_t out_offset = *j2 + *k2;
- CHECK_EQ(true, run_Unaligned<uint16_t>(
- buffer_middle, in_offset, out_offset, value,
- [](MacroAssembler* masm, int32_t in_offset,
- int32_t out_offset) {
- __ Ulh(v0, MemOperand(a0, in_offset));
- __ Ush(v0, MemOperand(a0, out_offset), v0);
- }));
- CHECK_EQ(true, run_Unaligned<uint16_t>(
- buffer_middle, in_offset, out_offset, value,
- [](MacroAssembler* masm, int32_t in_offset,
- int32_t out_offset) {
- __ mov(t0, a0);
- __ Ulh(a0, MemOperand(a0, in_offset));
- __ Ush(a0, MemOperand(t0, out_offset), v0);
- }));
- CHECK_EQ(true, run_Unaligned<uint16_t>(
- buffer_middle, in_offset, out_offset, value,
- [](MacroAssembler* masm, int32_t in_offset,
- int32_t out_offset) {
- __ mov(t0, a0);
- __ Ulhu(a0, MemOperand(a0, in_offset));
- __ Ush(a0, MemOperand(t0, out_offset), t1);
- }));
- CHECK_EQ(true, run_Unaligned<uint16_t>(
- buffer_middle, in_offset, out_offset, value,
- [](MacroAssembler* masm, int32_t in_offset,
- int32_t out_offset) {
- __ Ulhu(v0, MemOperand(a0, in_offset));
- __ Ush(v0, MemOperand(a0, out_offset), t1);
- }));
+ auto fn_1 = [](MacroAssembler* masm, int32_t in_offset,
+ int32_t out_offset) {
+ __ Ulh(v0, MemOperand(a0, in_offset));
+ __ Ush(v0, MemOperand(a0, out_offset), v0);
+ };
+ CHECK_EQ(true, run_Unaligned<uint16_t>(buffer_middle, in_offset,
+ out_offset, value, fn_1));
+
+ auto fn_2 = [](MacroAssembler* masm, int32_t in_offset,
+ int32_t out_offset) {
+ __ mov(t0, a0);
+ __ Ulh(a0, MemOperand(a0, in_offset));
+ __ Ush(a0, MemOperand(t0, out_offset), v0);
+ };
+ CHECK_EQ(true, run_Unaligned<uint16_t>(buffer_middle, in_offset,
+ out_offset, value, fn_2));
+
+ auto fn_3 = [](MacroAssembler* masm, int32_t in_offset,
+ int32_t out_offset) {
+ __ mov(t0, a0);
+ __ Ulhu(a0, MemOperand(a0, in_offset));
+ __ Ush(a0, MemOperand(t0, out_offset), t1);
+ };
+ CHECK_EQ(true, run_Unaligned<uint16_t>(buffer_middle, in_offset,
+ out_offset, value, fn_3));
+
+ auto fn_4 = [](MacroAssembler* masm, int32_t in_offset,
+ int32_t out_offset) {
+ __ Ulhu(v0, MemOperand(a0, in_offset));
+ __ Ush(v0, MemOperand(a0, out_offset), t1);
+ };
+ CHECK_EQ(true, run_Unaligned<uint16_t>(buffer_middle, in_offset,
+ out_offset, value, fn_4));
}
}
}
@@ -1582,39 +1677,39 @@ TEST(Ulh_bitextension) {
int32_t in_offset = *j1 + *k1;
int32_t out_offset = *j2 + *k2;
- CHECK_EQ(true, run_Unaligned<uint16_t>(
- buffer_middle, in_offset, out_offset, value,
- [](MacroAssembler* masm, int32_t in_offset,
- int32_t out_offset) {
- Label success, fail, end, different;
- __ Ulh(t0, MemOperand(a0, in_offset));
- __ Ulhu(t1, MemOperand(a0, in_offset));
- __ Branch(&different, ne, t0, Operand(t1));
-
- // If signed and unsigned values are same, check
- // the upper bits to see if they are zero
- __ sra(t0, t0, 15);
- __ Branch(&success, eq, t0, Operand(zero_reg));
- __ Branch(&fail);
-
- // If signed and unsigned values are different,
- // check that the upper bits are complementary
- __ bind(&different);
- __ sra(t1, t1, 15);
- __ Branch(&fail, ne, t1, Operand(1));
- __ sra(t0, t0, 15);
- __ addiu(t0, t0, 1);
- __ Branch(&fail, ne, t0, Operand(zero_reg));
- // Fall through to success
-
- __ bind(&success);
- __ Ulh(t0, MemOperand(a0, in_offset));
- __ Ush(t0, MemOperand(a0, out_offset), v0);
- __ Branch(&end);
- __ bind(&fail);
- __ Ush(zero_reg, MemOperand(a0, out_offset), v0);
- __ bind(&end);
- }));
+ auto fn = [](MacroAssembler* masm, int32_t in_offset,
+ int32_t out_offset) {
+ Label success, fail, end, different;
+ __ Ulh(t0, MemOperand(a0, in_offset));
+ __ Ulhu(t1, MemOperand(a0, in_offset));
+ __ Branch(&different, ne, t0, Operand(t1));
+
+ // If signed and unsigned values are same, check
+ // the upper bits to see if they are zero
+ __ sra(t0, t0, 15);
+ __ Branch(&success, eq, t0, Operand(zero_reg));
+ __ Branch(&fail);
+
+ // If signed and unsigned values are different,
+ // check that the upper bits are complementary
+ __ bind(&different);
+ __ sra(t1, t1, 15);
+ __ Branch(&fail, ne, t1, Operand(1));
+ __ sra(t0, t0, 15);
+ __ addiu(t0, t0, 1);
+ __ Branch(&fail, ne, t0, Operand(zero_reg));
+ // Fall through to success
+
+ __ bind(&success);
+ __ Ulh(t0, MemOperand(a0, in_offset));
+ __ Ush(t0, MemOperand(a0, out_offset), v0);
+ __ Branch(&end);
+ __ bind(&fail);
+ __ Ush(zero_reg, MemOperand(a0, out_offset), v0);
+ __ bind(&end);
+ };
+ CHECK_EQ(true, run_Unaligned<uint16_t>(buffer_middle, in_offset,
+ out_offset, value, fn));
}
}
}
@@ -1634,38 +1729,41 @@ TEST(Ulw) {
int32_t in_offset = *j1 + *k1;
int32_t out_offset = *j2 + *k2;
- CHECK_EQ(true, run_Unaligned<uint32_t>(
- buffer_middle, in_offset, out_offset, value,
- [](MacroAssembler* masm, int32_t in_offset,
- int32_t out_offset) {
- __ Ulw(v0, MemOperand(a0, in_offset));
- __ Usw(v0, MemOperand(a0, out_offset));
- }));
+ auto fn_1 = [](MacroAssembler* masm, int32_t in_offset,
+ int32_t out_offset) {
+ __ Ulw(v0, MemOperand(a0, in_offset));
+ __ Usw(v0, MemOperand(a0, out_offset));
+ };
+ CHECK_EQ(true, run_Unaligned<uint32_t>(buffer_middle, in_offset,
+ out_offset, value, fn_1));
+
+ auto fn_2 = [](MacroAssembler* masm, int32_t in_offset,
+ int32_t out_offset) {
+ __ mov(t0, a0);
+ __ Ulw(a0, MemOperand(a0, in_offset));
+ __ Usw(a0, MemOperand(t0, out_offset));
+ };
CHECK_EQ(true,
- run_Unaligned<uint32_t>(
- buffer_middle, in_offset, out_offset, (uint32_t)value,
- [](MacroAssembler* masm, int32_t in_offset,
- int32_t out_offset) {
- __ mov(t0, a0);
- __ Ulw(a0, MemOperand(a0, in_offset));
- __ Usw(a0, MemOperand(t0, out_offset));
- }));
- CHECK_EQ(true, run_Unaligned<uint32_t>(
- buffer_middle, in_offset, out_offset, value,
- [](MacroAssembler* masm, int32_t in_offset,
- int32_t out_offset) {
- __ Ulwu(v0, MemOperand(a0, in_offset));
- __ Usw(v0, MemOperand(a0, out_offset));
- }));
+ run_Unaligned<uint32_t>(buffer_middle, in_offset, out_offset,
+ (uint32_t)value, fn_2));
+
+ auto fn_3 = [](MacroAssembler* masm, int32_t in_offset,
+ int32_t out_offset) {
+ __ Ulwu(v0, MemOperand(a0, in_offset));
+ __ Usw(v0, MemOperand(a0, out_offset));
+ };
+ CHECK_EQ(true, run_Unaligned<uint32_t>(buffer_middle, in_offset,
+ out_offset, value, fn_3));
+
+ auto fn_4 = [](MacroAssembler* masm, int32_t in_offset,
+ int32_t out_offset) {
+ __ mov(t0, a0);
+ __ Ulwu(a0, MemOperand(a0, in_offset));
+ __ Usw(a0, MemOperand(t0, out_offset));
+ };
CHECK_EQ(true,
- run_Unaligned<uint32_t>(
- buffer_middle, in_offset, out_offset, (uint32_t)value,
- [](MacroAssembler* masm, int32_t in_offset,
- int32_t out_offset) {
- __ mov(t0, a0);
- __ Ulwu(a0, MemOperand(a0, in_offset));
- __ Usw(a0, MemOperand(t0, out_offset));
- }));
+ run_Unaligned<uint32_t>(buffer_middle, in_offset, out_offset,
+ (uint32_t)value, fn_4));
}
}
}
@@ -1685,39 +1783,39 @@ TEST(Ulw_extension) {
int32_t in_offset = *j1 + *k1;
int32_t out_offset = *j2 + *k2;
- CHECK_EQ(true, run_Unaligned<uint32_t>(
- buffer_middle, in_offset, out_offset, value,
- [](MacroAssembler* masm, int32_t in_offset,
- int32_t out_offset) {
- Label success, fail, end, different;
- __ Ulw(t0, MemOperand(a0, in_offset));
- __ Ulwu(t1, MemOperand(a0, in_offset));
- __ Branch(&different, ne, t0, Operand(t1));
-
- // If signed and unsigned values are same, check
- // the upper bits to see if they are zero
- __ dsra(t0, t0, 31);
- __ Branch(&success, eq, t0, Operand(zero_reg));
- __ Branch(&fail);
-
- // If signed and unsigned values are different,
- // check that the upper bits are complementary
- __ bind(&different);
- __ dsra(t1, t1, 31);
- __ Branch(&fail, ne, t1, Operand(1));
- __ dsra(t0, t0, 31);
- __ daddiu(t0, t0, 1);
- __ Branch(&fail, ne, t0, Operand(zero_reg));
- // Fall through to success
-
- __ bind(&success);
- __ Ulw(t0, MemOperand(a0, in_offset));
- __ Usw(t0, MemOperand(a0, out_offset));
- __ Branch(&end);
- __ bind(&fail);
- __ Usw(zero_reg, MemOperand(a0, out_offset));
- __ bind(&end);
- }));
+ auto fn = [](MacroAssembler* masm, int32_t in_offset,
+ int32_t out_offset) {
+ Label success, fail, end, different;
+ __ Ulw(t0, MemOperand(a0, in_offset));
+ __ Ulwu(t1, MemOperand(a0, in_offset));
+ __ Branch(&different, ne, t0, Operand(t1));
+
+ // If signed and unsigned values are same, check
+ // the upper bits to see if they are zero
+ __ dsra(t0, t0, 31);
+ __ Branch(&success, eq, t0, Operand(zero_reg));
+ __ Branch(&fail);
+
+ // If signed and unsigned values are different,
+ // check that the upper bits are complementary
+ __ bind(&different);
+ __ dsra(t1, t1, 31);
+ __ Branch(&fail, ne, t1, Operand(1));
+ __ dsra(t0, t0, 31);
+ __ daddiu(t0, t0, 1);
+ __ Branch(&fail, ne, t0, Operand(zero_reg));
+ // Fall through to success
+
+ __ bind(&success);
+ __ Ulw(t0, MemOperand(a0, in_offset));
+ __ Usw(t0, MemOperand(a0, out_offset));
+ __ Branch(&end);
+ __ bind(&fail);
+ __ Usw(zero_reg, MemOperand(a0, out_offset));
+ __ bind(&end);
+ };
+ CHECK_EQ(true, run_Unaligned<uint32_t>(buffer_middle, in_offset,
+ out_offset, value, fn));
}
}
}
@@ -1737,22 +1835,23 @@ TEST(Uld) {
int32_t in_offset = *j1 + *k1;
int32_t out_offset = *j2 + *k2;
- CHECK_EQ(true, run_Unaligned<uint64_t>(
- buffer_middle, in_offset, out_offset, value,
- [](MacroAssembler* masm, int32_t in_offset,
- int32_t out_offset) {
- __ Uld(v0, MemOperand(a0, in_offset));
- __ Usd(v0, MemOperand(a0, out_offset));
- }));
+ auto fn_1 = [](MacroAssembler* masm, int32_t in_offset,
+ int32_t out_offset) {
+ __ Uld(v0, MemOperand(a0, in_offset));
+ __ Usd(v0, MemOperand(a0, out_offset));
+ };
+ CHECK_EQ(true, run_Unaligned<uint64_t>(buffer_middle, in_offset,
+ out_offset, value, fn_1));
+
+ auto fn_2 = [](MacroAssembler* masm, int32_t in_offset,
+ int32_t out_offset) {
+ __ mov(t0, a0);
+ __ Uld(a0, MemOperand(a0, in_offset));
+ __ Usd(a0, MemOperand(t0, out_offset));
+ };
CHECK_EQ(true,
- run_Unaligned<uint64_t>(
- buffer_middle, in_offset, out_offset, (uint32_t)value,
- [](MacroAssembler* masm, int32_t in_offset,
- int32_t out_offset) {
- __ mov(t0, a0);
- __ Uld(a0, MemOperand(a0, in_offset));
- __ Usd(a0, MemOperand(t0, out_offset));
- }));
+ run_Unaligned<uint64_t>(buffer_middle, in_offset, out_offset,
+ (uint32_t)value, fn_2));
}
}
}
@@ -1772,13 +1871,13 @@ TEST(Ulwc1) {
int32_t in_offset = *j1 + *k1;
int32_t out_offset = *j2 + *k2;
- CHECK_EQ(true, run_Unaligned<float>(
- buffer_middle, in_offset, out_offset, value,
- [](MacroAssembler* masm, int32_t in_offset,
- int32_t out_offset) {
- __ Ulwc1(f0, MemOperand(a0, in_offset), t0);
- __ Uswc1(f0, MemOperand(a0, out_offset), t0);
- }));
+ auto fn = [](MacroAssembler* masm, int32_t in_offset,
+ int32_t out_offset) {
+ __ Ulwc1(f0, MemOperand(a0, in_offset), t0);
+ __ Uswc1(f0, MemOperand(a0, out_offset), t0);
+ };
+ CHECK_EQ(true, run_Unaligned<float>(buffer_middle, in_offset,
+ out_offset, value, fn));
}
}
}
@@ -1798,13 +1897,13 @@ TEST(Uldc1) {
int32_t in_offset = *j1 + *k1;
int32_t out_offset = *j2 + *k2;
- CHECK_EQ(true, run_Unaligned<double>(
- buffer_middle, in_offset, out_offset, value,
- [](MacroAssembler* masm, int32_t in_offset,
- int32_t out_offset) {
- __ Uldc1(f0, MemOperand(a0, in_offset), t0);
- __ Usdc1(f0, MemOperand(a0, out_offset), t0);
- }));
+ auto fn = [](MacroAssembler* masm, int32_t in_offset,
+ int32_t out_offset) {
+ __ Uldc1(f0, MemOperand(a0, in_offset), t0);
+ __ Usdc1(f0, MemOperand(a0, out_offset), t0);
+ };
+ CHECK_EQ(true, run_Unaligned<double>(buffer_middle, in_offset,
+ out_offset, value, fn));
}
}
}
@@ -1863,15 +1962,303 @@ TEST(Sltu) {
uint64_t rs = *i;
uint64_t rd = *j;
- CHECK_EQ(rs < rd, run_Sltu(rs, rd,
- [](MacroAssembler* masm, uint64_t imm) {
- __ Sltu(v0, a0, Operand(imm));
- }));
- CHECK_EQ(rs < rd,
- run_Sltu(rs, rd, [](MacroAssembler* masm,
- uint64_t imm) { __ Sltu(v0, a0, a1); }));
+ auto fn_1 = [](MacroAssembler* masm, uint64_t imm) {
+ __ Sltu(v0, a0, Operand(imm));
+ };
+ CHECK_EQ(rs < rd, run_Sltu(rs, rd, fn_1));
+
+ auto fn_2 = [](MacroAssembler* masm, uint64_t imm) {
+ __ Sltu(v0, a0, a1);
+ };
+ CHECK_EQ(rs < rd, run_Sltu(rs, rd, fn_2));
}
}
}
+template <typename T, typename Inputs, typename Results>
+static ::F4 GenerateMacroFloat32MinMax(MacroAssembler* masm) {
+ T a = T::from_code(4); // f4
+ T b = T::from_code(6); // f6
+ T c = T::from_code(8); // f8
+
+ Label ool_min_abc, ool_min_aab, ool_min_aba;
+ Label ool_max_abc, ool_max_aab, ool_max_aba;
+
+ Label done_min_abc, done_min_aab, done_min_aba;
+ Label done_max_abc, done_max_aab, done_max_aba;
+
+#define FLOAT_MIN_MAX(fminmax, res, x, y, done, ool, res_field) \
+ __ lwc1(x, MemOperand(a0, offsetof(Inputs, src1_))); \
+ __ lwc1(y, MemOperand(a0, offsetof(Inputs, src2_))); \
+ __ fminmax(res, x, y, &ool); \
+ __ bind(&done); \
+ __ swc1(a, MemOperand(a1, offsetof(Results, res_field)))
+
+ // a = min(b, c);
+ FLOAT_MIN_MAX(Float32Min, a, b, c, done_min_abc, ool_min_abc, min_abc_);
+ // a = min(a, b);
+ FLOAT_MIN_MAX(Float32Min, a, a, b, done_min_aab, ool_min_aab, min_aab_);
+ // a = min(b, a);
+ FLOAT_MIN_MAX(Float32Min, a, b, a, done_min_aba, ool_min_aba, min_aba_);
+
+ // a = max(b, c);
+ FLOAT_MIN_MAX(Float32Max, a, b, c, done_max_abc, ool_max_abc, max_abc_);
+ // a = max(a, b);
+ FLOAT_MIN_MAX(Float32Max, a, a, b, done_max_aab, ool_max_aab, max_aab_);
+ // a = max(b, a);
+ FLOAT_MIN_MAX(Float32Max, a, b, a, done_max_aba, ool_max_aba, max_aba_);
+
+#undef FLOAT_MIN_MAX
+
+ __ jr(ra);
+ __ nop();
+
+ // Generate out-of-line cases.
+ __ bind(&ool_min_abc);
+ __ Float32MinOutOfLine(a, b, c);
+ __ Branch(&done_min_abc);
+
+ __ bind(&ool_min_aab);
+ __ Float32MinOutOfLine(a, a, b);
+ __ Branch(&done_min_aab);
+
+ __ bind(&ool_min_aba);
+ __ Float32MinOutOfLine(a, b, a);
+ __ Branch(&done_min_aba);
+
+ __ bind(&ool_max_abc);
+ __ Float32MaxOutOfLine(a, b, c);
+ __ Branch(&done_max_abc);
+
+ __ bind(&ool_max_aab);
+ __ Float32MaxOutOfLine(a, a, b);
+ __ Branch(&done_max_aab);
+
+ __ bind(&ool_max_aba);
+ __ Float32MaxOutOfLine(a, b, a);
+ __ Branch(&done_max_aba);
+
+ CodeDesc desc;
+ masm->GetCode(&desc);
+ Handle<Code> code = masm->isolate()->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef DEBUG
+ OFStream os(stdout);
+ code->Print(os);
+#endif
+ return FUNCTION_CAST<::F4>(code->entry());
+}
+
+TEST(macro_float_minmax_f32) {
+ // Test the Float32Min and Float32Max macros.
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assembler(isolate, NULL, 0,
+ v8::internal::CodeObjectRequired::kYes);
+ MacroAssembler* masm = &assembler;
+
+ struct Inputs {
+ float src1_;
+ float src2_;
+ };
+
+ struct Results {
+ // Check all register aliasing possibilities in order to exercise all
+ // code-paths in the macro assembler.
+ float min_abc_;
+ float min_aab_;
+ float min_aba_;
+ float max_abc_;
+ float max_aab_;
+ float max_aba_;
+ };
+
+ ::F4 f = GenerateMacroFloat32MinMax<FPURegister, Inputs, Results>(masm);
+ Object* dummy = nullptr;
+ USE(dummy);
+
+#define CHECK_MINMAX(src1, src2, min, max) \
+ do { \
+ Inputs inputs = {src1, src2}; \
+ Results results; \
+ dummy = CALL_GENERATED_CODE(isolate, f, &inputs, &results, 0, 0, 0); \
+ CHECK_EQ(bit_cast<uint32_t>(min), bit_cast<uint32_t>(results.min_abc_)); \
+ CHECK_EQ(bit_cast<uint32_t>(min), bit_cast<uint32_t>(results.min_aab_)); \
+ CHECK_EQ(bit_cast<uint32_t>(min), bit_cast<uint32_t>(results.min_aba_)); \
+ CHECK_EQ(bit_cast<uint32_t>(max), bit_cast<uint32_t>(results.max_abc_)); \
+ CHECK_EQ(bit_cast<uint32_t>(max), bit_cast<uint32_t>(results.max_aab_)); \
+ CHECK_EQ(bit_cast<uint32_t>(max), bit_cast<uint32_t>(results.max_aba_)); \
+ /* Use a bit_cast to correctly identify -0.0 and NaNs. */ \
+ } while (0)
+
+ float nan_a = std::numeric_limits<float>::quiet_NaN();
+ float nan_b = std::numeric_limits<float>::quiet_NaN();
+
+ CHECK_MINMAX(1.0f, -1.0f, -1.0f, 1.0f);
+ CHECK_MINMAX(-1.0f, 1.0f, -1.0f, 1.0f);
+ CHECK_MINMAX(0.0f, -1.0f, -1.0f, 0.0f);
+ CHECK_MINMAX(-1.0f, 0.0f, -1.0f, 0.0f);
+ CHECK_MINMAX(-0.0f, -1.0f, -1.0f, -0.0f);
+ CHECK_MINMAX(-1.0f, -0.0f, -1.0f, -0.0f);
+ CHECK_MINMAX(0.0f, 1.0f, 0.0f, 1.0f);
+ CHECK_MINMAX(1.0f, 0.0f, 0.0f, 1.0f);
+
+ CHECK_MINMAX(0.0f, 0.0f, 0.0f, 0.0f);
+ CHECK_MINMAX(-0.0f, -0.0f, -0.0f, -0.0f);
+ CHECK_MINMAX(-0.0f, 0.0f, -0.0f, 0.0f);
+ CHECK_MINMAX(0.0f, -0.0f, -0.0f, 0.0f);
+
+ CHECK_MINMAX(0.0f, nan_a, nan_a, nan_a);
+ CHECK_MINMAX(nan_a, 0.0f, nan_a, nan_a);
+ CHECK_MINMAX(nan_a, nan_b, nan_a, nan_a);
+ CHECK_MINMAX(nan_b, nan_a, nan_b, nan_b);
+
+#undef CHECK_MINMAX
+}
+
+template <typename T, typename Inputs, typename Results>
+static ::F4 GenerateMacroFloat64MinMax(MacroAssembler* masm) {
+ T a = T::from_code(4); // f4
+ T b = T::from_code(6); // f6
+ T c = T::from_code(8); // f8
+
+ Label ool_min_abc, ool_min_aab, ool_min_aba;
+ Label ool_max_abc, ool_max_aab, ool_max_aba;
+
+ Label done_min_abc, done_min_aab, done_min_aba;
+ Label done_max_abc, done_max_aab, done_max_aba;
+
+#define FLOAT_MIN_MAX(fminmax, res, x, y, done, ool, res_field) \
+ __ ldc1(x, MemOperand(a0, offsetof(Inputs, src1_))); \
+ __ ldc1(y, MemOperand(a0, offsetof(Inputs, src2_))); \
+ __ fminmax(res, x, y, &ool); \
+ __ bind(&done); \
+ __ sdc1(a, MemOperand(a1, offsetof(Results, res_field)))
+
+ // a = min(b, c);
+ FLOAT_MIN_MAX(Float64Min, a, b, c, done_min_abc, ool_min_abc, min_abc_);
+ // a = min(a, b);
+ FLOAT_MIN_MAX(Float64Min, a, a, b, done_min_aab, ool_min_aab, min_aab_);
+ // a = min(b, a);
+ FLOAT_MIN_MAX(Float64Min, a, b, a, done_min_aba, ool_min_aba, min_aba_);
+
+ // a = max(b, c);
+ FLOAT_MIN_MAX(Float64Max, a, b, c, done_max_abc, ool_max_abc, max_abc_);
+ // a = max(a, b);
+ FLOAT_MIN_MAX(Float64Max, a, a, b, done_max_aab, ool_max_aab, max_aab_);
+ // a = max(b, a);
+ FLOAT_MIN_MAX(Float64Max, a, b, a, done_max_aba, ool_max_aba, max_aba_);
+
+#undef FLOAT_MIN_MAX
+
+ __ jr(ra);
+ __ nop();
+
+ // Generate out-of-line cases.
+ __ bind(&ool_min_abc);
+ __ Float64MinOutOfLine(a, b, c);
+ __ Branch(&done_min_abc);
+
+ __ bind(&ool_min_aab);
+ __ Float64MinOutOfLine(a, a, b);
+ __ Branch(&done_min_aab);
+
+ __ bind(&ool_min_aba);
+ __ Float64MinOutOfLine(a, b, a);
+ __ Branch(&done_min_aba);
+
+ __ bind(&ool_max_abc);
+ __ Float64MaxOutOfLine(a, b, c);
+ __ Branch(&done_max_abc);
+
+ __ bind(&ool_max_aab);
+ __ Float64MaxOutOfLine(a, a, b);
+ __ Branch(&done_max_aab);
+
+ __ bind(&ool_max_aba);
+ __ Float64MaxOutOfLine(a, b, a);
+ __ Branch(&done_max_aba);
+
+ CodeDesc desc;
+ masm->GetCode(&desc);
+ Handle<Code> code = masm->isolate()->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef DEBUG
+ OFStream os(stdout);
+ code->Print(os);
+#endif
+ return FUNCTION_CAST<::F4>(code->entry());
+}
+
+TEST(macro_float_minmax_f64) {
+ // Test the Float64Min and Float64Max macros.
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assembler(isolate, NULL, 0,
+ v8::internal::CodeObjectRequired::kYes);
+ MacroAssembler* masm = &assembler;
+
+ struct Inputs {
+ double src1_;
+ double src2_;
+ };
+
+ struct Results {
+ // Check all register aliasing possibilities in order to exercise all
+ // code-paths in the macro assembler.
+ double min_abc_;
+ double min_aab_;
+ double min_aba_;
+ double max_abc_;
+ double max_aab_;
+ double max_aba_;
+ };
+
+ ::F4 f = GenerateMacroFloat64MinMax<DoubleRegister, Inputs, Results>(masm);
+ Object* dummy = nullptr;
+ USE(dummy);
+
+#define CHECK_MINMAX(src1, src2, min, max) \
+ do { \
+ Inputs inputs = {src1, src2}; \
+ Results results; \
+ dummy = CALL_GENERATED_CODE(isolate, f, &inputs, &results, 0, 0, 0); \
+ CHECK_EQ(bit_cast<uint64_t>(min), bit_cast<uint64_t>(results.min_abc_)); \
+ CHECK_EQ(bit_cast<uint64_t>(min), bit_cast<uint64_t>(results.min_aab_)); \
+ CHECK_EQ(bit_cast<uint64_t>(min), bit_cast<uint64_t>(results.min_aba_)); \
+ CHECK_EQ(bit_cast<uint64_t>(max), bit_cast<uint64_t>(results.max_abc_)); \
+ CHECK_EQ(bit_cast<uint64_t>(max), bit_cast<uint64_t>(results.max_aab_)); \
+ CHECK_EQ(bit_cast<uint64_t>(max), bit_cast<uint64_t>(results.max_aba_)); \
+ /* Use a bit_cast to correctly identify -0.0 and NaNs. */ \
+ } while (0)
+
+ double nan_a = std::numeric_limits<double>::quiet_NaN();
+ double nan_b = std::numeric_limits<double>::quiet_NaN();
+
+ CHECK_MINMAX(1.0, -1.0, -1.0, 1.0);
+ CHECK_MINMAX(-1.0, 1.0, -1.0, 1.0);
+ CHECK_MINMAX(0.0, -1.0, -1.0, 0.0);
+ CHECK_MINMAX(-1.0, 0.0, -1.0, 0.0);
+ CHECK_MINMAX(-0.0, -1.0, -1.0, -0.0);
+ CHECK_MINMAX(-1.0, -0.0, -1.0, -0.0);
+ CHECK_MINMAX(0.0, 1.0, 0.0, 1.0);
+ CHECK_MINMAX(1.0, 0.0, 0.0, 1.0);
+
+ CHECK_MINMAX(0.0, 0.0, 0.0, 0.0);
+ CHECK_MINMAX(-0.0, -0.0, -0.0, -0.0);
+ CHECK_MINMAX(-0.0, 0.0, -0.0, 0.0);
+ CHECK_MINMAX(0.0, -0.0, -0.0, 0.0);
+
+ CHECK_MINMAX(0.0, nan_a, nan_a, nan_a);
+ CHECK_MINMAX(nan_a, 0.0, nan_a, nan_a);
+ CHECK_MINMAX(nan_a, nan_b, nan_a, nan_a);
+ CHECK_MINMAX(nan_b, nan_a, nan_b, nan_b);
+
+#undef CHECK_MINMAX
+}
+
#undef __
diff --git a/deps/v8/test/cctest/test-object.cc b/deps/v8/test/cctest/test-object.cc
index 396318121a..cade4284ae 100644
--- a/deps/v8/test/cctest/test-object.cc
+++ b/deps/v8/test/cctest/test-object.cc
@@ -6,6 +6,7 @@
#include "src/handles-inl.h"
#include "src/handles.h"
#include "src/isolate.h"
+#include "src/objects-inl.h"
#include "src/objects.h"
#include "src/v8.h"
#include "test/cctest/cctest.h"
diff --git a/deps/v8/test/cctest/test-parsing.cc b/deps/v8/test/cctest/test-parsing.cc
index 5a5a734236..fd904b110c 100644
--- a/deps/v8/test/cctest/test-parsing.cc
+++ b/deps/v8/test/cctest/test-parsing.cc
@@ -40,13 +40,16 @@
#include "src/execution.h"
#include "src/flags.h"
#include "src/isolate.h"
+#include "src/objects-inl.h"
#include "src/objects.h"
#include "src/parsing/parse-info.h"
#include "src/parsing/parser.h"
+#include "src/parsing/parsing.h"
#include "src/parsing/preparser.h"
#include "src/parsing/rewriter.h"
#include "src/parsing/scanner-character-streams.h"
#include "src/parsing/token.h"
+#include "src/unicode-cache.h"
#include "src/utils.h"
#include "test/cctest/cctest.h"
@@ -172,12 +175,13 @@ TEST(ScanHTMLEndComments) {
scanner.Initialize(stream.get());
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
i::AstValueFactory ast_value_factory(
- &zone, CcTest::i_isolate()->heap()->HashSeed());
+ &zone, CcTest::i_isolate()->ast_string_constants(),
+ CcTest::i_isolate()->heap()->HashSeed());
i::PendingCompilationErrorHandler pending_error_handler;
i::PreParser preparser(
- &zone, &scanner, &ast_value_factory, &pending_error_handler,
- CcTest::i_isolate()->counters()->runtime_call_stats(), stack_limit);
- preparser.set_allow_lazy(true);
+ &zone, &scanner, stack_limit, &ast_value_factory,
+ &pending_error_handler,
+ CcTest::i_isolate()->counters()->runtime_call_stats());
i::PreParser::PreParseResult result = preparser.PreParseProgram();
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
CHECK(!pending_error_handler.has_pending_error());
@@ -190,12 +194,13 @@ TEST(ScanHTMLEndComments) {
scanner.Initialize(stream.get());
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
i::AstValueFactory ast_value_factory(
- &zone, CcTest::i_isolate()->heap()->HashSeed());
+ &zone, CcTest::i_isolate()->ast_string_constants(),
+ CcTest::i_isolate()->heap()->HashSeed());
i::PendingCompilationErrorHandler pending_error_handler;
i::PreParser preparser(
- &zone, &scanner, &ast_value_factory, &pending_error_handler,
- CcTest::i_isolate()->counters()->runtime_call_stats(), stack_limit);
- preparser.set_allow_lazy(true);
+ &zone, &scanner, stack_limit, &ast_value_factory,
+ &pending_error_handler,
+ CcTest::i_isolate()->counters()->runtime_call_stats());
i::PreParser::PreParseResult result = preparser.PreParseProgram();
// Even in the case of a syntax error, kPreParseSuccess is returned.
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
@@ -251,7 +256,6 @@ TEST(UsingCachedData) {
v8::String::NewExternalOneByte(isolate,
new ScriptResource(source, source_length))
.ToLocalChecked());
- i::FLAG_min_preparse_length = 0;
v8::ScriptCompiler::Compile(isolate->GetCurrentContext(), &script_source,
v8::ScriptCompiler::kProduceParserCache)
.ToLocalChecked();
@@ -278,9 +282,6 @@ TEST(PreparseFunctionDataIsUsed) {
// This tests that we actually do use the function data generated by the
// preparser.
- // Make preparsing work for short scripts.
- i::FLAG_min_preparse_length = 0;
-
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope handles(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
@@ -365,12 +366,13 @@ TEST(StandAlonePreParser) {
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
i::AstValueFactory ast_value_factory(
- &zone, CcTest::i_isolate()->heap()->HashSeed());
+ &zone, CcTest::i_isolate()->ast_string_constants(),
+ CcTest::i_isolate()->heap()->HashSeed());
i::PendingCompilationErrorHandler pending_error_handler;
i::PreParser preparser(
- &zone, &scanner, &ast_value_factory, &pending_error_handler,
- CcTest::i_isolate()->counters()->runtime_call_stats(), stack_limit);
- preparser.set_allow_lazy(true);
+ &zone, &scanner, stack_limit, &ast_value_factory,
+ &pending_error_handler,
+ CcTest::i_isolate()->counters()->runtime_call_stats());
preparser.set_allow_natives(true);
i::PreParser::PreParseResult result = preparser.PreParseProgram();
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
@@ -401,12 +403,12 @@ TEST(StandAlonePreParserNoNatives) {
// Preparser defaults to disallowing natives syntax.
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
i::AstValueFactory ast_value_factory(
- &zone, CcTest::i_isolate()->heap()->HashSeed());
+ &zone, CcTest::i_isolate()->ast_string_constants(),
+ CcTest::i_isolate()->heap()->HashSeed());
i::PendingCompilationErrorHandler pending_error_handler;
- i::PreParser preparser(
- &zone, &scanner, &ast_value_factory, &pending_error_handler,
- isolate->counters()->runtime_call_stats(), stack_limit);
- preparser.set_allow_lazy(true);
+ i::PreParser preparser(&zone, &scanner, stack_limit, &ast_value_factory,
+ &pending_error_handler,
+ isolate->counters()->runtime_call_stats());
i::PreParser::PreParseResult result = preparser.PreParseProgram();
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
CHECK(pending_error_handler.has_pending_error());
@@ -468,14 +470,14 @@ TEST(RegressChromium62639) {
i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
scanner.Initialize(stream.get());
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
- i::AstValueFactory ast_value_factory(&zone,
- CcTest::i_isolate()->heap()->HashSeed());
+ i::AstValueFactory ast_value_factory(
+ &zone, CcTest::i_isolate()->ast_string_constants(),
+ CcTest::i_isolate()->heap()->HashSeed());
i::PendingCompilationErrorHandler pending_error_handler;
- i::PreParser preparser(&zone, &scanner, &ast_value_factory,
- &pending_error_handler,
- isolate->counters()->runtime_call_stats(),
- CcTest::i_isolate()->stack_guard()->real_climit());
- preparser.set_allow_lazy(true);
+ i::PreParser preparser(&zone, &scanner,
+ CcTest::i_isolate()->stack_guard()->real_climit(),
+ &ast_value_factory, &pending_error_handler,
+ isolate->counters()->runtime_call_stats());
i::PreParser::PreParseResult result = preparser.PreParseProgram();
// Even in the case of a syntax error, kPreParseSuccess is returned.
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
@@ -486,7 +488,6 @@ TEST(RegressChromium62639) {
TEST(Regress928) {
// Test only applies when lazy parsing.
if (!i::FLAG_lazy) return;
- i::FLAG_min_preparse_length = 0;
// Tests that the first non-toplevel function is not included in the preparse
// data.
@@ -545,13 +546,13 @@ TEST(PreParseOverflow) {
scanner.Initialize(stream.get());
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
- i::AstValueFactory ast_value_factory(&zone,
- CcTest::i_isolate()->heap()->HashSeed());
+ i::AstValueFactory ast_value_factory(
+ &zone, CcTest::i_isolate()->ast_string_constants(),
+ CcTest::i_isolate()->heap()->HashSeed());
i::PendingCompilationErrorHandler pending_error_handler;
- i::PreParser preparser(
- &zone, &scanner, &ast_value_factory, &pending_error_handler,
- isolate->counters()->runtime_call_stats(), stack_limit);
- preparser.set_allow_lazy(true);
+ i::PreParser preparser(&zone, &scanner, stack_limit, &ast_value_factory,
+ &pending_error_handler,
+ isolate->counters()->runtime_call_stats());
i::PreParser::PreParseResult result = preparser.PreParseProgram();
CHECK_EQ(i::PreParser::kPreParseStackOverflow, result);
}
@@ -647,8 +648,9 @@ void TestScanRegExp(const char* re_source, const char* expected) {
CHECK(scanner.ScanRegExpPattern());
scanner.Next(); // Current token is now the regexp literal.
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
- i::AstValueFactory ast_value_factory(&zone,
- CcTest::i_isolate()->heap()->HashSeed());
+ i::AstValueFactory ast_value_factory(
+ &zone, CcTest::i_isolate()->ast_string_constants(),
+ CcTest::i_isolate()->heap()->HashSeed());
const i::AstRawString* current_symbol =
scanner.CurrentSymbol(&ast_value_factory);
ast_value_factory.Internalize(CcTest::i_isolate());
@@ -825,8 +827,9 @@ TEST(ScopeUsesArgumentsSuperThis) {
i::Handle<i::Script> script = factory->NewScript(source);
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
i::ParseInfo info(&zone, script);
- i::Parser parser(&info);
- CHECK(parser.Parse(&info));
+ // The information we're checking is only produced when eager parsing.
+ info.set_allow_lazy_parsing(false);
+ CHECK(i::parsing::ParseProgram(&info));
CHECK(i::Rewriter::Rewrite(&info));
i::DeclarationScope::Analyze(&info, i::AnalyzeMode::kRegular);
CHECK(info.literal() != NULL);
@@ -1179,11 +1182,9 @@ TEST(ScopePositions) {
i::Handle<i::Script> script = factory->NewScript(source);
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
i::ParseInfo info(&zone, script);
- i::Parser parser(&info);
- parser.set_allow_lazy(true);
info.set_language_mode(source_data[i].language_mode);
- parser.Parse(&info);
- CHECK(info.literal() != NULL);
+ i::parsing::ParseProgram(&info);
+ CHECK_NOT_NULL(info.literal());
// Check scope types and positions.
i::Scope* scope = info.literal()->scope();
@@ -1228,9 +1229,7 @@ TEST(DiscardFunctionBody) {
i::Handle<i::Script> script = factory->NewScript(source_code);
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
i::ParseInfo info(&zone, script);
- info.set_allow_lazy_parsing();
- i::Parser parser(&info);
- parser.Parse(&info);
+ i::parsing::ParseProgram(&info);
function = info.literal();
CHECK_NOT_NULL(function);
CHECK_NOT_NULL(function->body());
@@ -1278,15 +1277,14 @@ const char* ReadString(unsigned* start) {
return result;
}
-
enum ParserFlag {
kAllowLazy,
kAllowNatives,
kAllowHarmonyFunctionSent,
- kAllowHarmonyAsyncAwait,
kAllowHarmonyRestrictiveGenerators,
kAllowHarmonyTrailingCommas,
kAllowHarmonyClassFields,
+ kAllowHarmonyObjectSpread,
};
enum ParserSyncTestResult {
@@ -1295,24 +1293,30 @@ enum ParserSyncTestResult {
kError
};
-template <typename Traits>
-void SetParserFlags(i::ParserBase<Traits>* parser,
- i::EnumSet<ParserFlag> flags) {
- parser->set_allow_lazy(flags.Contains(kAllowLazy));
+void SetGlobalFlags(i::EnumSet<ParserFlag> flags) {
+ i::FLAG_allow_natives_syntax = flags.Contains(kAllowNatives);
+ i::FLAG_harmony_function_sent = flags.Contains(kAllowHarmonyFunctionSent);
+ i::FLAG_harmony_restrictive_generators =
+ flags.Contains(kAllowHarmonyRestrictiveGenerators);
+ i::FLAG_harmony_trailing_commas = flags.Contains(kAllowHarmonyTrailingCommas);
+ i::FLAG_harmony_class_fields = flags.Contains(kAllowHarmonyClassFields);
+ i::FLAG_harmony_object_spread = flags.Contains(kAllowHarmonyObjectSpread);
+}
+
+void SetParserFlags(i::PreParser* parser, i::EnumSet<ParserFlag> flags) {
parser->set_allow_natives(flags.Contains(kAllowNatives));
parser->set_allow_harmony_function_sent(
flags.Contains(kAllowHarmonyFunctionSent));
- parser->set_allow_harmony_async_await(
- flags.Contains(kAllowHarmonyAsyncAwait));
parser->set_allow_harmony_restrictive_generators(
flags.Contains(kAllowHarmonyRestrictiveGenerators));
parser->set_allow_harmony_trailing_commas(
flags.Contains(kAllowHarmonyTrailingCommas));
parser->set_allow_harmony_class_fields(
flags.Contains(kAllowHarmonyClassFields));
+ parser->set_allow_harmony_object_spread(
+ flags.Contains(kAllowHarmonyObjectSpread));
}
-
void TestParserSyncWithFlags(i::Handle<i::String> source,
i::EnumSet<ParserFlag> flags,
ParserSyncTestResult result,
@@ -1333,10 +1337,11 @@ void TestParserSyncWithFlags(i::Handle<i::String> source,
i::ScannerStream::For(source));
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
i::AstValueFactory ast_value_factory(
- &zone, CcTest::i_isolate()->heap()->HashSeed());
- i::PreParser preparser(
- &zone, &scanner, &ast_value_factory, &pending_error_handler,
- isolate->counters()->runtime_call_stats(), stack_limit);
+ &zone, CcTest::i_isolate()->ast_string_constants(),
+ CcTest::i_isolate()->heap()->HashSeed());
+ i::PreParser preparser(&zone, &scanner, stack_limit, &ast_value_factory,
+ &pending_error_handler,
+ isolate->counters()->runtime_call_stats());
SetParserFlags(&preparser, flags);
scanner.Initialize(stream.get());
i::PreParser::PreParseResult result =
@@ -1350,10 +1355,10 @@ void TestParserSyncWithFlags(i::Handle<i::String> source,
i::Handle<i::Script> script = factory->NewScript(source);
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
i::ParseInfo info(&zone, script);
- i::Parser parser(&info);
- SetParserFlags(&parser, flags);
+ info.set_allow_lazy_parsing(flags.Contains(kAllowLazy));
+ SetGlobalFlags(flags);
if (is_module) info.set_module();
- parser.Parse(&info);
+ i::parsing::ParseProgram(&info);
function = info.literal();
if (function) {
parser_materialized_literals = function->materialized_literal_count();
@@ -2485,8 +2490,7 @@ TEST(DontRegressPreParserDataSizes) {
i::ScriptData* sd = NULL;
info.set_cached_data(&sd);
info.set_compile_options(v8::ScriptCompiler::kProduceParserCache);
- info.set_allow_lazy_parsing();
- i::Parser::ParseStatic(&info);
+ i::parsing::ParseProgram(&info);
i::ParseData* pd = i::ParseData::FromCachedData(sd);
if (pd->FunctionCount() != test_cases[i].functions) {
@@ -2727,16 +2731,6 @@ TEST(ErrorsObjectLiteralChecking) {
"x = 0",
"* *x(){}",
"x*(){}",
- // This should fail without --harmony-async-await
- "async x(){}",
- NULL
- };
- // clang-format on
-
- RunParserSyncTest(context_data, statement_data, kError);
-
- // clang-format off
- const char* async_data[] = {
"static async x(){}",
"static async x : 0",
"static async get x : 0",
@@ -2754,9 +2748,7 @@ TEST(ErrorsObjectLiteralChecking) {
};
// clang-format on
- static const ParserFlag always_flags[] = {kAllowHarmonyAsyncAwait};
- RunParserSyncTest(context_data, async_data, kError, NULL, 0, always_flags,
- arraysize(always_flags));
+ RunParserSyncTest(context_data, statement_data, kError);
}
@@ -2830,14 +2822,6 @@ TEST(NoErrorsObjectLiteralChecking) {
"super: 6",
"eval: 7",
"arguments: 8",
- NULL
- };
- // clang-format on
-
- RunParserSyncTest(context_data, statement_data, kSuccess);
-
- // clang-format off
- const char* async_data[] = {
"async x(){}",
"async 0(){}",
"async get(){}",
@@ -2851,9 +2835,7 @@ TEST(NoErrorsObjectLiteralChecking) {
};
// clang-format on
- static const ParserFlag always_flags[] = {kAllowHarmonyAsyncAwait};
- RunParserSyncTest(context_data, async_data, kSuccess, NULL, 0, always_flags,
- arraysize(always_flags));
+ RunParserSyncTest(context_data, statement_data, kSuccess);
}
@@ -3151,7 +3133,6 @@ TEST(RegressionLazyFunctionWithErrorWithArg) {
v8::HandleScope scope(isolate);
LocalContext env;
i::FLAG_lazy = true;
- i::FLAG_min_preparse_length = 0;
CompileRun("function this_is_lazy() {\n"
" break p;\n"
"}\n"
@@ -3191,7 +3172,8 @@ TEST(SerializationOfMaybeAssignmentFlag) {
i::Handle<i::Object> o = v8::Utils::OpenHandle(*v);
i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o);
i::Context* context = f->context();
- i::AstValueFactory avf(&zone, isolate->heap()->HashSeed());
+ i::AstValueFactory avf(&zone, isolate->ast_string_constants(),
+ isolate->heap()->HashSeed());
const i::AstRawString* name = avf.GetOneByteString("result");
avf.Internalize(isolate);
i::Handle<i::String> str = name->string();
@@ -3220,7 +3202,6 @@ TEST(IfArgumentsArrayAccessedThenParametersMaybeAssigned) {
i::HandleScope scope(isolate);
LocalContext env;
-
const char* src =
"function f(x) {"
" var a = arguments;"
@@ -3236,12 +3217,13 @@ TEST(IfArgumentsArrayAccessedThenParametersMaybeAssigned) {
i::Handle<i::String> source = factory->InternalizeUtf8String(program.start());
source->PrintOn(stdout);
printf("\n");
- i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
+ i::Zone zone(isolate->allocator(), ZONE_NAME);
v8::Local<v8::Value> v = CompileRun(src);
i::Handle<i::Object> o = v8::Utils::OpenHandle(*v);
i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o);
i::Context* context = f->context();
- i::AstValueFactory avf(&zone, isolate->heap()->HashSeed());
+ i::AstValueFactory avf(&zone, isolate->ast_string_constants(),
+ isolate->heap()->HashSeed());
const i::AstRawString* name_x = avf.GetOneByteString("x");
avf.Internalize(isolate);
@@ -3268,83 +3250,109 @@ TEST(InnerAssignment) {
const char* prefix = "function f() {";
const char* midfix = " function g() {";
const char* suffix = "}}; f";
- struct { const char* source; bool assigned; bool strict; } outers[] = {
- // Actual assignments.
- { "var x; var x = 5;", true, false },
- { "var x; { var x = 5; }", true, false },
- { "'use strict'; let x; x = 6;", true, true },
- { "var x = 5; function x() {}", true, false },
- // Actual non-assignments.
- { "var x;", false, false },
- { "var x = 5;", false, false },
- { "'use strict'; let x;", false, true },
- { "'use strict'; let x = 6;", false, true },
- { "'use strict'; var x = 0; { let x = 6; }", false, true },
- { "'use strict'; var x = 0; { let x; x = 6; }", false, true },
- { "'use strict'; let x = 0; { let x = 6; }", false, true },
- { "'use strict'; let x = 0; { let x; x = 6; }", false, true },
- { "var x; try {} catch (x) { x = 5; }", false, false },
- { "function x() {}", false, false },
- // Eval approximation.
- { "var x; eval('');", true, false },
- { "eval(''); var x;", true, false },
- { "'use strict'; let x; eval('');", true, true },
- { "'use strict'; eval(''); let x;", true, true },
- // Non-assignments not recognized, because the analysis is approximative.
- { "var x; var x;", true, false },
- { "var x = 5; var x;", true, false },
- { "var x; { var x; }", true, false },
- { "var x; function x() {}", true, false },
- { "function x() {}; var x;", true, false },
- { "var x; try {} catch (x) { var x = 5; }", true, false },
- };
- struct { const char* source; bool assigned; bool with; } inners[] = {
- // Actual assignments.
- { "x = 1;", true, false },
- { "x++;", true, false },
- { "++x;", true, false },
- { "x--;", true, false },
- { "--x;", true, false },
- { "{ x = 1; }", true, false },
- { "'use strict'; { let x; }; x = 0;", true, false },
- { "'use strict'; { const x = 1; }; x = 0;", true, false },
- { "'use strict'; { function x() {} }; x = 0;", true, false },
- { "with ({}) { x = 1; }", true, true },
- { "eval('');", true, false },
- { "'use strict'; { let y; eval('') }", true, false },
- { "function h() { x = 0; }", true, false },
- { "(function() { x = 0; })", true, false },
- { "(function() { x = 0; })", true, false },
- { "with ({}) (function() { x = 0; })", true, true },
- // Actual non-assignments.
- { "", false, false },
- { "x;", false, false },
- { "var x;", false, false },
- { "var x = 8;", false, false },
- { "var x; x = 8;", false, false },
- { "'use strict'; let x;", false, false },
- { "'use strict'; let x = 8;", false, false },
- { "'use strict'; let x; x = 8;", false, false },
- { "'use strict'; const x = 8;", false, false },
- { "function x() {}", false, false },
- { "function x() { x = 0; }", false, false },
- { "function h(x) { x = 0; }", false, false },
- { "'use strict'; { let x; x = 0; }", false, false },
- { "{ var x; }; x = 0;", false, false },
- { "with ({}) {}", false, true },
- { "var x; { with ({}) { x = 1; } }", false, true },
- { "try {} catch(x) { x = 0; }", false, false },
- { "try {} catch(x) { with ({}) { x = 1; } }", false, true },
- // Eval approximation.
- { "eval('');", true, false },
- { "function h() { eval(''); }", true, false },
- { "(function() { eval(''); })", true, false },
- // Shadowing not recognized because of eval approximation.
- { "var x; eval('');", true, false },
- { "'use strict'; let x; eval('');", true, false },
- { "try {} catch(x) { eval(''); }", true, false },
- { "function x() { eval(''); }", true, false },
- { "(function(x) { eval(''); })", true, false },
+ struct {
+ const char* source;
+ bool assigned;
+ bool strict;
+ } outers[] = {
+ // Actual assignments.
+ {"var x; var x = 5;", true, false},
+ {"var x; { var x = 5; }", true, false},
+ {"'use strict'; let x; x = 6;", true, true},
+ {"var x = 5; function x() {}", true, false},
+ {"var x = 4; var x = 5;", true, false},
+ {"var [x, x] = [4, 5];", true, false},
+ {"var x; [x, x] = [4, 5];", true, false},
+ {"var {a: x, b: x} = {a: 4, b: 5};", true, false},
+ {"var x = {a: 4, b: (x = 5)};", true, false},
+ {"var {x=1} = {a: 4, b: (x = 5)};", true, false},
+ {"var {x} = {x: 4, b: (x = 5)};", true, false},
+ // Actual non-assignments.
+ {"var x;", false, false},
+ {"var x = 5;", false, false},
+ {"'use strict'; let x;", false, true},
+ {"'use strict'; let x = 6;", false, true},
+ {"'use strict'; var x = 0; { let x = 6; }", false, true},
+ {"'use strict'; var x = 0; { let x; x = 6; }", false, true},
+ {"'use strict'; let x = 0; { let x = 6; }", false, true},
+ {"'use strict'; let x = 0; { let x; x = 6; }", false, true},
+ {"var x; try {} catch (x) { x = 5; }", false, false},
+ {"function x() {}", false, false},
+ // Eval approximation.
+ {"var x; eval('');", true, false},
+ {"eval(''); var x;", true, false},
+ {"'use strict'; let x; eval('');", true, true},
+ {"'use strict'; eval(''); let x;", true, true},
+ // Non-assignments not recognized, because the analysis is approximative.
+ {"var x; var x;", true, false},
+ {"var x = 5; var x;", true, false},
+ {"var x; { var x; }", true, false},
+ {"var x; function x() {}", true, false},
+ {"function x() {}; var x;", true, false},
+ {"var x; try {} catch (x) { var x = 5; }", true, false},
+ };
+
+ // We set allow_error_in_inner_function to true in cases where our handling of
+ // assigned variables in lazy inner functions is currently overly pessimistic.
+ // FIXME(marja): remove it when no longer needed.
+ struct {
+ const char* source;
+ bool assigned;
+ bool with;
+ bool allow_error_in_inner_function;
+ } inners[] = {
+ // Actual assignments.
+ {"x = 1;", true, false, false},
+ {"x++;", true, false, false},
+ {"++x;", true, false, false},
+ {"x--;", true, false, false},
+ {"--x;", true, false, false},
+ {"{ x = 1; }", true, false, false},
+ {"'use strict'; { let x; }; x = 0;", true, false, false},
+ {"'use strict'; { const x = 1; }; x = 0;", true, false, false},
+ {"'use strict'; { function x() {} }; x = 0;", true, false, false},
+ {"with ({}) { x = 1; }", true, true, false},
+ {"eval('');", true, false, false},
+ {"'use strict'; { let y; eval('') }", true, false, false},
+ {"function h() { x = 0; }", true, false, false},
+ {"(function() { x = 0; })", true, false, false},
+ {"(function() { x = 0; })", true, false, false},
+ {"with ({}) (function() { x = 0; })", true, true, false},
+ {"for (x of [1,2,3]) {}", true, false, false},
+ {"for (x in {a: 1}) {}", true, false, false},
+ {"for ([x] of [[1],[2],[3]]) {}", true, false, false},
+ {"for ([x] in {ab: 1}) {}", true, false, false},
+ {"for ([...x] in {ab: 1}) {}", true, false, false},
+ {"[x] = [1]", true, false, false},
+ // Actual non-assignments.
+ {"", false, false, false},
+ {"x;", false, false, false},
+ {"var x;", false, false, false},
+ {"var x = 8;", false, false, false},
+ {"var x; x = 8;", false, false, false},
+ {"'use strict'; let x;", false, false, false},
+ {"'use strict'; let x = 8;", false, false, false},
+ {"'use strict'; let x; x = 8;", false, false, false},
+ {"'use strict'; const x = 8;", false, false, false},
+ {"function x() {}", false, false, false},
+ {"function x() { x = 0; }", false, false, true},
+ {"function h(x) { x = 0; }", false, false, false},
+ {"'use strict'; { let x; x = 0; }", false, false, false},
+ {"{ var x; }; x = 0;", false, false, false},
+ {"with ({}) {}", false, true, false},
+ {"var x; { with ({}) { x = 1; } }", false, true, false},
+ {"try {} catch(x) { x = 0; }", false, false, true},
+ {"try {} catch(x) { with ({}) { x = 1; } }", false, true, true},
+ // Eval approximation.
+ {"eval('');", true, false, false},
+ {"function h() { eval(''); }", true, false, false},
+ {"(function() { eval(''); })", true, false, false},
+ // Shadowing not recognized because of eval approximation.
+ {"var x; eval('');", true, false, false},
+ {"'use strict'; let x; eval('');", true, false, false},
+ {"try {} catch(x) { eval(''); }", true, false, false},
+ {"function x() { eval(''); }", true, false, false},
+ {"(function(x) { eval(''); })", true, false, false},
};
int prefix_len = Utf8LengthHelper(prefix);
@@ -3365,7 +3373,7 @@ TEST(InnerAssignment) {
i::SNPrintF(program, "%s%s%s%s%s", prefix, outer, midfix, inner,
suffix);
- i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
+ i::Zone zone(isolate->allocator(), ZONE_NAME);
std::unique_ptr<i::ParseInfo> info;
if (lazy) {
printf("%s\n", program.start());
@@ -3374,6 +3382,7 @@ TEST(InnerAssignment) {
i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o);
i::Handle<i::SharedFunctionInfo> shared = i::handle(f->shared());
info = std::unique_ptr<i::ParseInfo>(new i::ParseInfo(&zone, shared));
+ CHECK(i::parsing::ParseFunction(info.get()));
} else {
i::Handle<i::String> source =
factory->InternalizeUtf8String(program.start());
@@ -3381,9 +3390,9 @@ TEST(InnerAssignment) {
printf("\n");
i::Handle<i::Script> script = factory->NewScript(source);
info = std::unique_ptr<i::ParseInfo>(new i::ParseInfo(&zone, script));
+ info->set_allow_lazy_parsing(false);
+ CHECK(i::parsing::ParseProgram(info.get()));
}
- i::Parser parser(info.get());
- CHECK(parser.Parse(info.get()));
CHECK(i::Compiler::Analyze(info.get()));
CHECK(info->literal() != NULL);
@@ -3402,17 +3411,268 @@ TEST(InnerAssignment) {
CHECK(var->is_used() || !expected);
bool is_maybe_assigned = var->maybe_assigned() == i::kMaybeAssigned;
if (i::FLAG_lazy_inner_functions) {
- // If we parse inner functions lazily, allow being pessimistic about
- // maybe_assigned.
- CHECK(is_maybe_assigned || (is_maybe_assigned == expected));
+ CHECK(is_maybe_assigned == expected ||
+ (is_maybe_assigned && inners[j].allow_error_in_inner_function));
} else {
- CHECK(is_maybe_assigned == expected);
+ CHECK_EQ(is_maybe_assigned, expected);
}
}
}
}
}
+TEST(MaybeAssignedParameters) {
+ i::Isolate* isolate = CcTest::i_isolate();
+ i::HandleScope scope(isolate);
+ LocalContext env;
+
+ struct {
+ bool arg_assigned;
+ const char* source;
+ } tests[] = {
+ {false, "function f(arg) {}"},
+ {false, "function f(arg) {g(arg)}"},
+ {false, "function f(arg) {function h() { g(arg) }; h()}"},
+ {false, "function f(arg) {function h() { g(arg) }; return h}"},
+ {false, "function f(arg=1) {}"},
+ {false, "function f(arg=1) {g(arg)}"},
+ {false, "function f(arg, arguments) {g(arg); arguments[0] = 42; g(arg)}"},
+ {false,
+ "function f(arg, ...arguments) {g(arg); arguments[0] = 42; g(arg)}"},
+ {false,
+ "function f(arg, arguments=[]) {g(arg); arguments[0] = 42; g(arg)}"},
+ {false, "function f(...arg) {g(arg); arguments[0] = 42; g(arg)}"},
+ {false,
+ "function f(arg) {g(arg); g(function() {arguments[0] = 42}); g(arg)}"},
+
+ // strict arguments object
+ {false, "function f(arg, x=1) {g(arg); arguments[0] = 42; g(arg)}"},
+ {false, "function f(arg, ...x) {g(arg); arguments[0] = 42; g(arg)}"},
+ {false, "function f(arg=1) {g(arg); arguments[0] = 42; g(arg)}"},
+ {false,
+ "function f(arg) {'use strict'; g(arg); arguments[0] = 42; g(arg)}"},
+ {false, "function f(arg) {g(arg); f.arguments[0] = 42; g(arg)}"},
+ {false, "function f(arg, args=arguments) {g(arg); args[0] = 42; g(arg)}"},
+
+ {true, "function f(arg) {g(arg); arg = 42; g(arg)}"},
+ {true, "function f(arg) {g(arg); eval('arg = 42'); g(arg)}"},
+ {true, "function f(arg) {g(arg); var arg = 42; g(arg)}"},
+ {true, "function f(arg, x=1) {g(arg); arg = 42; g(arg)}"},
+ {true, "function f(arg, ...x) {g(arg); arg = 42; g(arg)}"},
+ {true, "function f(arg=1) {g(arg); arg = 42; g(arg)}"},
+ {true, "function f(arg) {'use strict'; g(arg); arg = 42; g(arg)}"},
+ {true, "function f(arg, {a=(g(arg), arg=42)}) {g(arg)}"},
+ {true, "function f(arg) {g(arg); g(function() {arg = 42}); g(arg)}"},
+ {true,
+ "function f(arg) {g(arg); g(function() {eval('arg = 42')}); g(arg)}"},
+ {true, "function f(arg) {g(arg); g(() => arg = 42); g(arg)}"},
+ {true, "function f(arg) {g(arg); g(() => eval('arg = 42')); g(arg)}"},
+ {true, "function f(...arg) {g(arg); eval('arg = 42'); g(arg)}"},
+
+ // sloppy arguments object
+ {true, "function f(arg) {g(arg); arguments[0] = 42; g(arg)}"},
+ {true, "function f(arg) {g(arg); h(arguments); g(arg)}"},
+ {true,
+ "function f(arg) {((args) => {arguments[0] = 42})(arguments); "
+ "g(arg)}"},
+ {true, "function f(arg) {g(arg); eval('arguments[0] = 42'); g(arg)}"},
+ {true, "function f(arg) {g(arg); g(() => arguments[0] = 42); g(arg)}"},
+ };
+
+ const char* suffix = "; f";
+
+ for (unsigned i = 0; i < arraysize(tests); ++i) {
+ bool assigned = tests[i].arg_assigned;
+ const char* source = tests[i].source;
+ for (unsigned allow_lazy = 0; allow_lazy < 2; ++allow_lazy) {
+ i::ScopedVector<char> program(Utf8LengthHelper(source) +
+ Utf8LengthHelper(suffix) + 1);
+ i::SNPrintF(program, "%s%s", source, suffix);
+ i::Zone zone(isolate->allocator(), ZONE_NAME);
+ std::unique_ptr<i::ParseInfo> info;
+ printf("%s\n", program.start());
+ v8::Local<v8::Value> v = CompileRun(program.start());
+ i::Handle<i::Object> o = v8::Utils::OpenHandle(*v);
+ i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o);
+ i::Handle<i::SharedFunctionInfo> shared = i::handle(f->shared());
+ info = std::unique_ptr<i::ParseInfo>(new i::ParseInfo(&zone, shared));
+ info->set_allow_lazy_parsing(allow_lazy);
+ CHECK(i::parsing::ParseFunction(info.get()));
+ CHECK(i::Compiler::Analyze(info.get()));
+ CHECK_NOT_NULL(info->literal());
+
+ i::Scope* scope = info->literal()->scope();
+ CHECK(!scope->AsDeclarationScope()->was_lazily_parsed());
+ CHECK_NULL(scope->sibling());
+ CHECK(scope->is_function_scope());
+ const i::AstRawString* var_name =
+ info->ast_value_factory()->GetOneByteString("arg");
+ i::Variable* var = scope->Lookup(var_name);
+ CHECK(var->is_used() || !assigned);
+ bool is_maybe_assigned = var->maybe_assigned() == i::kMaybeAssigned;
+ CHECK_EQ(is_maybe_assigned, assigned);
+ }
+ }
+}
+
+TEST(MaybeAssignedTopLevel) {
+ i::Isolate* isolate = CcTest::i_isolate();
+ i::HandleScope scope(isolate);
+ LocalContext env;
+ i::Factory* factory = isolate->factory();
+
+ const char* prefixes[] = {
+ "let foo; ", "let foo = 0; ",
+ "let [foo] = [1]; ", "let {foo} = {foo: 2}; ",
+ "let {foo=3} = {}; ",
+ };
+ const char* sources[] = {
+ "function bar() {foo = 42}; ext(bar); ext(foo)",
+ "ext(function() {foo++}); ext(foo)",
+ "bar = () => --foo; ext(bar); ext(foo)",
+ "function* bar() {eval(ext)}; ext(bar); ext(foo)",
+ };
+
+ for (unsigned i = 0; i < arraysize(prefixes); ++i) {
+ const char* prefix = prefixes[i];
+ for (unsigned j = 0; j < arraysize(sources); ++j) {
+ const char* source = sources[j];
+ i::ScopedVector<char> program(Utf8LengthHelper(prefix) +
+ Utf8LengthHelper(source) + 1);
+ i::SNPrintF(program, "%s%s", prefix, source);
+ i::Zone zone(isolate->allocator(), ZONE_NAME);
+
+ i::Handle<i::String> string =
+ factory->InternalizeUtf8String(program.start());
+ string->PrintOn(stdout);
+ printf("\n");
+ i::Handle<i::Script> script = factory->NewScript(string);
+
+ for (unsigned allow_lazy = 0; allow_lazy < 2; ++allow_lazy) {
+ for (unsigned module = 0; module < 2; ++module) {
+ std::unique_ptr<i::ParseInfo> info;
+ info = std::unique_ptr<i::ParseInfo>(new i::ParseInfo(&zone, script));
+ info->set_module(module);
+ info->set_allow_lazy_parsing(allow_lazy);
+
+ CHECK(i::parsing::ParseProgram(info.get()));
+ CHECK(i::Compiler::Analyze(info.get()));
+
+ CHECK_NOT_NULL(info->literal());
+ i::Scope* scope = info->literal()->scope();
+ CHECK(!scope->AsDeclarationScope()->was_lazily_parsed());
+ CHECK_NULL(scope->sibling());
+ CHECK(module ? scope->is_module_scope() : scope->is_script_scope());
+
+ const i::AstRawString* var_name =
+ info->ast_value_factory()->GetOneByteString("foo");
+ i::Variable* var = scope->Lookup(var_name);
+ CHECK(var->is_used());
+ CHECK(var->maybe_assigned() == i::kMaybeAssigned);
+ }
+ }
+ }
+ }
+}
+
+namespace {
+
+i::Scope* DeserializeFunctionScope(i::Isolate* isolate, i::Zone* zone,
+ i::Handle<i::JSObject> m, const char* name) {
+ i::AstValueFactory avf(zone, isolate->ast_string_constants(),
+ isolate->heap()->HashSeed());
+ i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(
+ i::JSReceiver::GetProperty(isolate, m, name).ToHandleChecked());
+ i::DeclarationScope* script_scope =
+ new (zone) i::DeclarationScope(zone, &avf);
+ i::Scope* s = i::Scope::DeserializeScopeChain(
+ isolate, zone, f->context()->scope_info(), script_scope, &avf,
+ i::Scope::DeserializationMode::kIncludingVariables);
+ return s;
+}
+
+} // namespace
+
+TEST(AsmModuleFlag) {
+ i::FLAG_validate_asm = false;
+ i::Isolate* isolate = CcTest::i_isolate();
+ i::HandleScope scope(isolate);
+ LocalContext env;
+
+ const char* src =
+ "function m() {"
+ " 'use asm';"
+ " function f() { return 0 };"
+ " return { f:f };"
+ "}"
+ "m();";
+
+ i::Zone zone(isolate->allocator(), ZONE_NAME);
+ v8::Local<v8::Value> v = CompileRun(src);
+ i::Handle<i::Object> o = v8::Utils::OpenHandle(*v);
+ i::Handle<i::JSObject> m = i::Handle<i::JSObject>::cast(o);
+
+ // The asm.js module should be marked as such.
+ i::Scope* s = DeserializeFunctionScope(isolate, &zone, m, "f");
+ CHECK(s->IsAsmModule() && s->AsDeclarationScope()->asm_module());
+ CHECK(!s->IsAsmFunction() && !s->AsDeclarationScope()->asm_function());
+}
+
+TEST(AsmFunctionFlag) {
+ i::Isolate* isolate = CcTest::i_isolate();
+ i::HandleScope scope(isolate);
+ LocalContext env;
+
+ const char* src =
+ "function m() {"
+ " 'use asm';"
+ " var x = 0;"
+ " function f1(a) {"
+ " var y = 0; return () => x + y;"
+ " };"
+ " do { function f2() {"
+ " var y = 0; return () => x + y;"
+ " } } while(false);"
+ " var f3 = (function() {"
+ " var y = 0; return () => x + y;"
+ " });"
+ " var f4 = (function() { return (function() {"
+ " var y = 0; return () => x + y;"
+ " }) })();"
+ " return { f1:f1(), f2:f2(), f3:f3(), f4:f4() };"
+ "}"
+ "m();";
+
+ i::Zone zone(isolate->allocator(), ZONE_NAME);
+ v8::Local<v8::Value> v = CompileRun(src);
+ i::Handle<i::Object> o = v8::Utils::OpenHandle(*v);
+ i::Handle<i::JSObject> m = i::Handle<i::JSObject>::cast(o);
+
+ // The asm.js function {f1} should be marked as such.
+ i::Scope* s1 = DeserializeFunctionScope(isolate, &zone, m, "f1");
+ CHECK(!s1->IsAsmModule() && !s1->AsDeclarationScope()->asm_module());
+ CHECK(s1->IsAsmFunction() && s1->AsDeclarationScope()->asm_function());
+
+ // The asm.js function {f2} should be marked as such.
+ // TODO(5653): If the block surrounding {f2} where to allocate a context we
+ // would actually determine {f2} not to be an asm.js function. That decision
+ // is fine but we should be consistent independent of whether a context is
+ // allocated for the surrounding block scope!
+ i::Scope* s2 = DeserializeFunctionScope(isolate, &zone, m, "f2");
+ CHECK(!s2->IsAsmModule() && !s2->AsDeclarationScope()->asm_module());
+ CHECK(s2->IsAsmFunction() && s2->AsDeclarationScope()->asm_function());
+
+ // The asm.js function {f3} should be marked as such.
+ i::Scope* s3 = DeserializeFunctionScope(isolate, &zone, m, "f3");
+ CHECK(!s3->IsAsmModule() && !s3->AsDeclarationScope()->asm_module());
+ CHECK(s3->IsAsmFunction() && s3->AsDeclarationScope()->asm_function());
+
+ // The nested function {f4} is not an asm.js function.
+ i::Scope* s4 = DeserializeFunctionScope(isolate, &zone, m, "f4");
+ CHECK(!s4->IsAsmModule() && !s4->AsDeclarationScope()->asm_module());
+ CHECK(!s4->IsAsmFunction() && !s4->AsDeclarationScope()->asm_function());
+}
+
namespace {
int* global_use_counts = NULL;
@@ -3422,8 +3682,7 @@ void MockUseCounterCallback(v8::Isolate* isolate,
++global_use_counts[feature];
}
-}
-
+} // namespace
TEST(UseAsmUseCount) {
i::Isolate* isolate = CcTest::i_isolate();
@@ -3460,6 +3719,8 @@ TEST(SloppyModeUseCount) {
LocalContext env;
int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
global_use_counts = use_counts;
+ // Force eager parsing (preparser doesn't update use counts).
+ i::FLAG_lazy = false;
CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
CompileRun("function bar() { var baz = 1; }");
CHECK_LT(0, use_counts[v8::Isolate::kSloppyMode]);
@@ -3473,6 +3734,8 @@ TEST(BothModesUseCount) {
LocalContext env;
int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
global_use_counts = use_counts;
+ // Force eager parsing (preparser doesn't update use counts).
+ i::FLAG_lazy = false;
CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
CompileRun("function bar() { 'use strict'; var baz = 1; }");
CHECK_LT(0, use_counts[v8::Isolate::kSloppyMode]);
@@ -4293,13 +4556,7 @@ TEST(ClassBodyNoErrors) {
"static set st\\u0061tic(v) {}",
"*st\\u0061tic() {}",
"static *st\\u0061tic() {}",
- NULL};
- // clang-format on
- RunParserSyncTest(context_data, class_body_data, kSuccess);
-
- // clang-format off
- const char* async_data[] = {
"static async x(){}",
"static async(){}",
"static *async(){}",
@@ -4311,13 +4568,10 @@ TEST(ClassBodyNoErrors) {
"async async(){}",
"async(){}",
"*async(){}",
- NULL
- };
+ NULL};
// clang-format on
- static const ParserFlag always_flags[] = {kAllowHarmonyAsyncAwait};
- RunParserSyncTest(context_data, async_data, kSuccess, NULL, 0, always_flags,
- arraysize(always_flags));
+ RunParserSyncTest(context_data, class_body_data, kSuccess);
}
@@ -4445,16 +4699,6 @@ TEST(ClassFieldsNoErrors) {
"yield",
"yield = 0",
"yield\n a",
- NULL
- };
- // clang-format on
-
- static const ParserFlag without_async[] = {kAllowHarmonyClassFields};
- RunParserSyncTest(context_data, class_body_data, kSuccess, NULL, 0,
- without_async, arraysize(without_async));
-
- // clang-format off
- const char* async_data[] = {
"async;",
"async = 0;",
"static async;"
@@ -4470,10 +4714,9 @@ TEST(ClassFieldsNoErrors) {
};
// clang-format on
- static const ParserFlag with_async[] = {kAllowHarmonyClassFields,
- kAllowHarmonyAsyncAwait};
- RunParserSyncTest(context_data, async_data, kSuccess, NULL, 0, with_async,
- arraysize(with_async));
+ static const ParserFlag always_flags[] = {kAllowHarmonyClassFields};
+ RunParserSyncTest(context_data, class_body_data, kSuccess, NULL, 0,
+ always_flags, arraysize(always_flags));
}
TEST(ClassFieldsErrors) {
@@ -4497,6 +4740,8 @@ TEST(ClassFieldsErrors) {
"*a;",
"get a;",
"yield a;",
+ "async a = 0",
+ "async a",
// ASI requires a linebreak
"a b",
@@ -4510,22 +4755,9 @@ TEST(ClassFieldsErrors) {
};
// clang-format on
- static const ParserFlag without_async[] = {kAllowHarmonyClassFields};
+ static const ParserFlag always_flags[] = {kAllowHarmonyClassFields};
RunParserSyncTest(context_data, class_body_data, kError, NULL, 0,
- without_async, arraysize(without_async));
-
- // clang-format off
- const char* async_data[] = {
- "async a = 0",
- "async a",
- NULL
- };
- // clang-format on
-
- static const ParserFlag with_async[] = {kAllowHarmonyClassFields,
- kAllowHarmonyAsyncAwait};
- RunParserSyncTest(context_data, async_data, kError, NULL, 0, with_async,
- arraysize(with_async));
+ always_flags, arraysize(always_flags));
}
TEST(ClassExpressionErrors) {
@@ -4614,13 +4846,7 @@ TEST(ClassAsyncErrors) {
};
// clang-format on
- // All of these are illegal whether or not async functions are permitted,
- // although for different reasons.
RunParserSyncTest(context_data, async_data, kError);
-
- static const ParserFlag always_flags[] = {kAllowHarmonyAsyncAwait};
- RunParserSyncTest(context_data, async_data, kError, NULL, 0, always_flags,
- arraysize(always_flags));
}
TEST(ClassNameErrors) {
@@ -5646,9 +5872,8 @@ TEST(BasicImportExportParsing) {
i::Handle<i::Script> script = factory->NewScript(source);
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
i::ParseInfo info(&zone, script);
- i::Parser parser(&info);
info.set_module();
- if (!parser.Parse(&info)) {
+ if (!i::parsing::ParseProgram(&info)) {
i::Handle<i::JSObject> exception_handle(
i::JSObject::cast(isolate->pending_exception()));
i::Handle<i::String> message_string = i::Handle<i::String>::cast(
@@ -5672,8 +5897,7 @@ TEST(BasicImportExportParsing) {
i::Handle<i::Script> script = factory->NewScript(source);
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
i::ParseInfo info(&zone, script);
- i::Parser parser(&info);
- CHECK(!parser.Parse(&info));
+ CHECK(!i::parsing::ParseProgram(&info));
isolate->clear_pending_exception();
}
}
@@ -5764,9 +5988,8 @@ TEST(ImportExportParsingErrors) {
i::Handle<i::Script> script = factory->NewScript(source);
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
i::ParseInfo info(&zone, script);
- i::Parser parser(&info);
info.set_module();
- CHECK(!parser.Parse(&info));
+ CHECK(!i::parsing::ParseProgram(&info));
isolate->clear_pending_exception();
}
}
@@ -5802,9 +6025,8 @@ TEST(ModuleTopLevelFunctionDecl) {
i::Handle<i::Script> script = factory->NewScript(source);
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
i::ParseInfo info(&zone, script);
- i::Parser parser(&info);
info.set_module();
- CHECK(!parser.Parse(&info));
+ CHECK(!i::parsing::ParseProgram(&info));
isolate->clear_pending_exception();
}
}
@@ -6001,9 +6223,8 @@ TEST(ModuleParsingInternals) {
i::Handle<i::Script> script = factory->NewScript(source);
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
i::ParseInfo info(&zone, script);
- i::Parser parser(&info);
info.set_module();
- CHECK(parser.Parse(&info));
+ CHECK(i::parsing::ParseProgram(&info));
CHECK(i::Compiler::Analyze(&info));
i::FunctionLiteral* func = info.literal();
i::ModuleScope* module_scope = func->scope()->AsModuleScope();
@@ -6262,8 +6483,7 @@ void TestLanguageMode(const char* source,
factory->NewScript(factory->NewStringFromAsciiChecked(source));
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
i::ParseInfo info(&zone, script);
- i::Parser parser(&info);
- parser.Parse(&info);
+ i::parsing::ParseProgram(&info);
CHECK(info.literal() != NULL);
CHECK_EQ(expected_language_mode, info.literal()->language_mode());
}
@@ -6362,6 +6582,94 @@ TEST(ArrowFunctionASIErrors) {
RunParserSyncTest(context_data, data, kError);
}
+TEST(ObjectSpreadPositiveTests) {
+ // clang-format off
+ const char* context_data[][2] = {
+ {"x = ", ""},
+ {"'use strict'; x = ", ""},
+ {NULL, NULL}};
+
+ // clang-format off
+ const char* data[] = {
+ "{ ...y }",
+ "{ a: 1, ...y }",
+ "{ b: 1, ...y }",
+ "{ y, ...y}",
+ "{ ...z = y}",
+ "{ ...y, y }",
+ "{ ...y, ...y}",
+ "{ a: 1, ...y, b: 1}",
+ "{ ...y, b: 1}",
+ "{ ...1}",
+ "{ ...null}",
+ "{ ...undefined}",
+ "{ ...1 in {}}",
+ "{ ...[]}",
+ "{ ...async function() { }}",
+ "{ ...async () => { }}",
+ "{ ...new Foo()}",
+ NULL};
+
+ static const ParserFlag flags[] = {kAllowHarmonyObjectSpread};
+ RunParserSyncTest(context_data, data, kSuccess, NULL, 0, flags,
+ arraysize(flags));
+}
+
+TEST(ObjectSpreadNegativeTests) {
+ {
+ const char* context_data[][2] = {{"x = ", ""},
+ {"'use strict'; x = ", ""},
+ {NULL, NULL}};
+
+ // clang-format off
+ const char* data[] = {
+ "{ ...var z = y}",
+ "{ ...var}",
+ "{ ...foo bar}",
+ NULL};
+
+ static const ParserFlag flags[] = {kAllowHarmonyObjectSpread};
+ RunParserSyncTest(context_data, data, kError, NULL, 0, flags,
+ arraysize(flags));
+ }
+
+ // Destructuring tests
+ {
+ const char* context_data[][2] = {
+ {"var ", " = {};"},
+ {"( ", " = {});"},
+ {"'use strict'; const ", " = {};"},
+ {"function f(", ") {}"},
+ {"function f(argument1, ", ") {}"},
+ {"var f = (", ") => {};"},
+ {"var f = (argument1,", ") => {};"},
+ {"try {} catch(", ") {}"},
+ {NULL, NULL}};
+
+ // clang-format off
+ const char* data[] = {
+ "{ ...y }",
+ "{ a: 1, ...y }",
+ "{ b: 1, ...y }",
+ "{ y, ...y}",
+ "{ ...z = y}",
+ "{ ...y, y }",
+ "{ ...y, ...y}",
+ "{ a: 1, ...y, b: 1}",
+ "{ ...y, b: 1}",
+ "{ ...1}",
+ "{ ...null}",
+ "{ ...undefined}",
+ "{ ...unknown}",
+ "{ ...var z = y}",
+ "({ ...z = {})",
+ NULL};
+
+ static const ParserFlag flags[] = {kAllowHarmonyObjectSpread};
+ RunParserSyncTest(context_data, data, kError, NULL, 0, flags,
+ arraysize(flags));
+ }
+}
TEST(DestructuringPositiveTests) {
const char* context_data[][2] = {{"'use strict'; let ", " = {};"},
@@ -7802,9 +8110,7 @@ TEST(AsyncAwait) {
};
// clang-format on
- static const ParserFlag always_flags[] = {kAllowHarmonyAsyncAwait};
- RunParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags,
- arraysize(always_flags));
+ RunParserSyncTest(context_data, data, kSuccess);
// clang-format off
const char* async_body_context_data[][2] = {
@@ -7858,10 +8164,8 @@ TEST(AsyncAwait) {
};
// clang-format on
- RunParserSyncTest(async_body_context_data, body_data, kSuccess, NULL, 0,
- always_flags, arraysize(always_flags));
- RunParserSyncTest(body_context_data, body_data, kSuccess, NULL, 0,
- always_flags, arraysize(always_flags));
+ RunParserSyncTest(async_body_context_data, body_data, kSuccess);
+ RunParserSyncTest(body_context_data, body_data, kSuccess);
}
TEST(AsyncAwaitErrors) {
@@ -7998,14 +8302,9 @@ TEST(AsyncAwaitErrors) {
};
// clang-format on
- static const ParserFlag always_flags[] = {kAllowHarmonyAsyncAwait};
- RunParserSyncTest(context_data, error_data, kError, NULL, 0, always_flags,
- arraysize(always_flags));
- RunParserSyncTest(strict_context_data, strict_error_data, kError, NULL, 0,
- always_flags, arraysize(always_flags));
-
- RunParserSyncTest(context_data, formal_parameters_data, kError, NULL, 0,
- always_flags, arraysize(always_flags));
+ RunParserSyncTest(context_data, error_data, kError);
+ RunParserSyncTest(strict_context_data, strict_error_data, kError);
+ RunParserSyncTest(context_data, formal_parameters_data, kError);
// clang-format off
const char* async_body_context_data[][2] = {
@@ -8046,8 +8345,7 @@ TEST(AsyncAwaitErrors) {
};
// clang-format on
- RunParserSyncTest(async_body_context_data, async_body_error_data, kError,
- NULL, 0, always_flags, arraysize(always_flags));
+ RunParserSyncTest(async_body_context_data, async_body_error_data, kError);
}
TEST(AsyncAwaitModule) {
@@ -8065,9 +8363,8 @@ TEST(AsyncAwaitModule) {
};
// clang-format on
- static const ParserFlag always_flags[] = {kAllowHarmonyAsyncAwait};
- RunModuleParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags,
- arraysize(always_flags), NULL, 0, false);
+ RunModuleParserSyncTest(context_data, data, kSuccess, NULL, 0, NULL, 0, NULL,
+ 0, false);
}
TEST(AsyncAwaitModuleErrors) {
@@ -8087,10 +8384,8 @@ TEST(AsyncAwaitModuleErrors) {
};
// clang-format on
- static const ParserFlag always_flags[] = {kAllowHarmonyAsyncAwait};
- RunModuleParserSyncTest(context_data, error_data, kError, NULL, 0,
- always_flags, arraysize(always_flags), NULL, 0,
- false);
+ RunModuleParserSyncTest(context_data, error_data, kError, NULL, 0, NULL, 0,
+ NULL, 0, false);
}
TEST(RestrictiveForInErrors) {
@@ -8167,14 +8462,11 @@ TEST(NoDuplicateAsyncFunctionInBlock) {
"async function x() {} function* x() {}",
"function* x() {} async function x() {}",
NULL};
- static const ParserFlag always_flags[] = {kAllowHarmonyAsyncAwait};
// The preparser doesn't enforce the restriction, so turn it off.
bool test_preparser = false;
- RunParserSyncTest(block_context_data, error_data, kError, NULL, 0,
- always_flags, arraysize(always_flags), NULL, 0, false,
- test_preparser);
- RunParserSyncTest(top_level_context_data, error_data, kSuccess, NULL, 0,
- always_flags, arraysize(always_flags));
+ RunParserSyncTest(block_context_data, error_data, kError, NULL, 0, NULL, 0,
+ NULL, 0, false, test_preparser);
+ RunParserSyncTest(top_level_context_data, error_data, kSuccess);
}
TEST(TrailingCommasInParameters) {
@@ -8315,3 +8607,288 @@ TEST(ArgumentsRedeclaration) {
RunParserSyncTest(context_data, data, kSuccess);
}
}
+
+namespace v8 {
+namespace internal {
+
+class ScopeTestHelper {
+ public:
+ static bool MustAllocateInContext(Variable* var) {
+ return var->scope()->MustAllocateInContext(var);
+ }
+};
+} // namespace internal
+} // namespace v8
+
+// Test that lazily parsed inner functions don't result in overly pessimistic
+// context allocations.
+TEST(NoPessimisticContextAllocation) {
+ i::FLAG_lazy_inner_functions = true;
+ i::Isolate* isolate = CcTest::i_isolate();
+ i::Factory* factory = isolate->factory();
+ i::HandleScope scope(isolate);
+ LocalContext env;
+
+ const char* prefix = "(function outer() { var my_var; ";
+ const char* suffix = " })();";
+ int prefix_len = Utf8LengthHelper(prefix);
+ int suffix_len = Utf8LengthHelper(suffix);
+
+ // Test both normal inner functions and inner arrow functions.
+ const char* inner_functions[] = {"function inner(%s) { %s }",
+ "(%s) => { %s }"};
+
+ struct {
+ const char* params;
+ const char* source;
+ bool ctxt_allocate;
+ } inners[] = {
+ // Context allocating because we need to:
+ {"", "my_var;", true},
+ {"", "if (true) { let my_var; } my_var;", true},
+ {"", "eval(\"foo\");", true},
+ {"", "function inner2() { my_var; }", true},
+ {"", "function inner2() { eval(\"foo\"); }", true},
+ {"", "var {my_var : a} = {my_var};", true},
+ {"", "let {my_var : a} = {my_var};", true},
+ {"", "const {my_var : a} = {my_var};", true},
+ {"a = my_var", "", true},
+ {"", "function inner2(a = my_var) { }", true},
+ {"", "(a = my_var) => { }", true},
+ {"{a} = {a: my_var}", "", true},
+ {"", "function inner2({a} = {a: my_var}) { }", true},
+ {"", "({a} = {a: my_var}) => { }", true},
+ {"[a] = [my_var]", "", true},
+ {"", "function inner2([a] = [my_var]) { }", true},
+ {"", "([a] = [my_var]) => { }", true},
+ {"", "try { } catch (my_var) { } my_var;", true},
+ {"", "for (my_var in {}) { my_var; }", true},
+ {"", "for (my_var in {}) { }", true},
+ {"", "for (my_var of []) { my_var; }", true},
+ {"", "for (my_var of []) { }", true},
+ {"", "for ([a, my_var, b] in {}) { my_var; }", true},
+ {"", "for ([a, my_var, b] of []) { my_var; }", true},
+ {"", "for ({x: my_var} in {}) { my_var; }", true},
+ {"", "for ({x: my_var} of []) { my_var; }", true},
+ {"", "for ({my_var} in {}) { my_var; }", true},
+ {"", "for ({my_var} of []) { my_var; }", true},
+ {"", "for ({y, x: my_var} in {}) { my_var; }", true},
+ {"", "for ({y, x: my_var} of []) { my_var; }", true},
+ {"", "for ({a, my_var} in {}) { my_var; }", true},
+ {"", "for ({a, my_var} of []) { my_var; }", true},
+ {"", "for (let my_var in {}) { } my_var;", true},
+ {"", "for (let my_var of []) { } my_var;", true},
+ {"", "for (let [a, my_var, b] in {}) { } my_var;", true},
+ {"", "for (let [a, my_var, b] of []) { } my_var;", true},
+ {"", "for (let {x: my_var} in {}) { } my_var;", true},
+ {"", "for (let {x: my_var} of []) { } my_var;", true},
+ {"", "for (let {my_var} in {}) { } my_var;", true},
+ {"", "for (let {my_var} of []) { } my_var;", true},
+ {"", "for (let {y, x: my_var} in {}) { } my_var;", true},
+ {"", "for (let {y, x: my_var} of []) { } my_var;", true},
+ {"", "for (let {a, my_var} in {}) { } my_var;", true},
+ {"", "for (let {a, my_var} of []) { } my_var;", true},
+ {"", "for (let my_var = 0; my_var < 1; ++my_var) { } my_var;", true},
+ {"", "'use strict'; if (true) { function my_var() {} } my_var;", true},
+ {"",
+ "'use strict'; function inner2() { if (true) { function my_var() {} } "
+ "my_var; }",
+ true},
+ {"",
+ "function inner2() { 'use strict'; if (true) { function my_var() {} } "
+ "my_var; }",
+ true},
+ {"",
+ "() => { 'use strict'; if (true) { function my_var() {} } my_var; }",
+ true},
+ {"",
+ "if (true) { let my_var; if (true) { function my_var() {} } } my_var;",
+ true},
+ // No pessimistic context allocation:
+ {"", "var my_var; my_var;", false},
+ {"", "var my_var;", false},
+ {"", "var my_var = 0;", false},
+ {"", "if (true) { var my_var; } my_var;", false},
+ {"", "let my_var; my_var;", false},
+ {"", "let my_var;", false},
+ {"", "let my_var = 0;", false},
+ {"", "const my_var = 0; my_var;", false},
+ {"", "const my_var = 0;", false},
+ {"", "var [a, my_var] = [1, 2]; my_var;", false},
+ {"", "let [a, my_var] = [1, 2]; my_var;", false},
+ {"", "const [a, my_var] = [1, 2]; my_var;", false},
+ {"", "var {a: my_var} = {a: 3}; my_var;", false},
+ {"", "let {a: my_var} = {a: 3}; my_var;", false},
+ {"", "const {a: my_var} = {a: 3}; my_var;", false},
+ {"", "var {my_var} = {my_var: 3}; my_var;", false},
+ {"", "let {my_var} = {my_var: 3}; my_var;", false},
+ {"", "const {my_var} = {my_var: 3}; my_var;", false},
+ {"my_var", "my_var;", false},
+ {"my_var", "", false},
+ {"my_var = 5", "my_var;", false},
+ {"my_var = 5", "", false},
+ {"...my_var", "my_var;", false},
+ {"...my_var", "", false},
+ {"[a, my_var, b]", "my_var;", false},
+ {"[a, my_var, b]", "", false},
+ {"[a, my_var, b] = [1, 2, 3]", "my_var;", false},
+ {"[a, my_var, b] = [1, 2, 3]", "", false},
+ {"{x: my_var}", "my_var;", false},
+ {"{x: my_var}", "", false},
+ {"{x: my_var} = {x: 0}", "my_var;", false},
+ {"{x: my_var} = {x: 0}", "", false},
+ {"{my_var}", "my_var;", false},
+ {"{my_var}", "", false},
+ {"{my_var} = {my_var: 0}", "my_var;", false},
+ {"{my_var} = {my_var: 0}", "", false},
+ {"", "function inner2(my_var) { my_var; }", false},
+ {"", "function inner2(my_var) { }", false},
+ {"", "function inner2(my_var = 5) { my_var; }", false},
+ {"", "function inner2(my_var = 5) { }", false},
+ {"", "function inner2(...my_var) { my_var; }", false},
+ {"", "function inner2(...my_var) { }", false},
+ {"", "function inner2([a, my_var, b]) { my_var; }", false},
+ {"", "function inner2([a, my_var, b]) { }", false},
+ {"", "function inner2([a, my_var, b] = [1, 2, 3]) { my_var; }", false},
+ {"", "function inner2([a, my_var, b] = [1, 2, 3]) { }", false},
+ {"", "function inner2({x: my_var}) { my_var; }", false},
+ {"", "function inner2({x: my_var}) { }", false},
+ {"", "function inner2({x: my_var} = {x: 0}) { my_var; }", false},
+ {"", "function inner2({x: my_var} = {x: 0}) { }", false},
+ {"", "function inner2({my_var}) { my_var; }", false},
+ {"", "function inner2({my_var}) { }", false},
+ {"", "function inner2({my_var} = {my_var: 8}) { my_var; } ", false},
+ {"", "function inner2({my_var} = {my_var: 8}) { }", false},
+ {"", "my_var => my_var;", false},
+ {"", "my_var => { }", false},
+ {"", "(my_var = 5) => my_var;", false},
+ {"", "(my_var = 5) => { }", false},
+ {"", "(...my_var) => my_var;", false},
+ {"", "(...my_var) => { }", false},
+ {"", "([a, my_var, b]) => my_var;", false},
+ {"", "([a, my_var, b]) => { }", false},
+ {"", "([a, my_var, b] = [1, 2, 3]) => my_var;", false},
+ {"", "([a, my_var, b] = [1, 2, 3]) => { }", false},
+ {"", "({x: my_var}) => my_var;", false},
+ {"", "({x: my_var}) => { }", false},
+ {"", "({x: my_var} = {x: 0}) => my_var;", false},
+ {"", "({x: my_var} = {x: 0}) => { }", false},
+ {"", "({my_var}) => my_var;", false},
+ {"", "({my_var}) => { }", false},
+ {"", "({my_var} = {my_var: 5}) => my_var;", false},
+ {"", "({my_var} = {my_var: 5}) => { }", false},
+ {"", "({a, my_var}) => my_var;", false},
+ {"", "({a, my_var}) => { }", false},
+ {"", "({a, my_var} = {a: 0, my_var: 5}) => my_var;", false},
+ {"", "({a, my_var} = {a: 0, my_var: 5}) => { }", false},
+ {"", "({y, x: my_var}) => my_var;", false},
+ {"", "({y, x: my_var}) => { }", false},
+ {"", "({y, x: my_var} = {y: 0, x: 0}) => my_var;", false},
+ {"", "({y, x: my_var} = {y: 0, x: 0}) => { }", false},
+ {"", "try { } catch (my_var) { my_var; }", false},
+ {"", "try { } catch ([a, my_var, b]) { my_var; }", false},
+ {"", "try { } catch ({x: my_var}) { my_var; }", false},
+ {"", "try { } catch ({y, x: my_var}) { my_var; }", false},
+ {"", "try { } catch ({my_var}) { my_var; }", false},
+ {"", "for (let my_var in {}) { my_var; }", false},
+ {"", "for (let my_var in {}) { }", false},
+ {"", "for (let my_var of []) { my_var; }", false},
+ {"", "for (let my_var of []) { }", false},
+ {"", "for (let [a, my_var, b] in {}) { my_var; }", false},
+ {"", "for (let [a, my_var, b] of []) { my_var; }", false},
+ {"", "for (let {x: my_var} in {}) { my_var; }", false},
+ {"", "for (let {x: my_var} of []) { my_var; }", false},
+ {"", "for (let {my_var} in {}) { my_var; }", false},
+ {"", "for (let {my_var} of []) { my_var; }", false},
+ {"", "for (let {y, x: my_var} in {}) { my_var; }", false},
+ {"", "for (let {y, x: my_var} of []) { my_var; }", false},
+ {"", "for (let {a, my_var} in {}) { my_var; }", false},
+ {"", "for (let {a, my_var} of []) { my_var; }", false},
+ {"", "for (var my_var in {}) { my_var; }", false},
+ {"", "for (var my_var in {}) { }", false},
+ {"", "for (var my_var of []) { my_var; }", false},
+ {"", "for (var my_var of []) { }", false},
+ {"", "for (var [a, my_var, b] in {}) { my_var; }", false},
+ {"", "for (var [a, my_var, b] of []) { my_var; }", false},
+ {"", "for (var {x: my_var} in {}) { my_var; }", false},
+ {"", "for (var {x: my_var} of []) { my_var; }", false},
+ {"", "for (var {my_var} in {}) { my_var; }", false},
+ {"", "for (var {my_var} of []) { my_var; }", false},
+ {"", "for (var {y, x: my_var} in {}) { my_var; }", false},
+ {"", "for (var {y, x: my_var} of []) { my_var; }", false},
+ {"", "for (var {a, my_var} in {}) { my_var; }", false},
+ {"", "for (var {a, my_var} of []) { my_var; }", false},
+ {"", "for (var my_var in {}) { } my_var;", false},
+ {"", "for (var my_var of []) { } my_var;", false},
+ {"", "for (var [a, my_var, b] in {}) { } my_var;", false},
+ {"", "for (var [a, my_var, b] of []) { } my_var;", false},
+ {"", "for (var {x: my_var} in {}) { } my_var;", false},
+ {"", "for (var {x: my_var} of []) { } my_var;", false},
+ {"", "for (var {my_var} in {}) { } my_var;", false},
+ {"", "for (var {my_var} of []) { } my_var;", false},
+ {"", "for (var {y, x: my_var} in {}) { } my_var;", false},
+ {"", "for (var {y, x: my_var} of []) { } my_var;", false},
+ {"", "for (var {a, my_var} in {}) { } my_var;", false},
+ {"", "for (var {a, my_var} of []) { } my_var;", false},
+ {"", "for (let my_var = 0; my_var < 1; ++my_var) { my_var; }", false},
+ {"", "for (var my_var = 0; my_var < 1; ++my_var) { my_var; }", false},
+ {"", "for (var my_var = 0; my_var < 1; ++my_var) { } my_var; ", false},
+ {"", "for (let a = 0, my_var = 0; my_var < 1; ++my_var) { my_var }",
+ false},
+ {"", "for (var a = 0, my_var = 0; my_var < 1; ++my_var) { my_var }",
+ false},
+ {"", "class my_var {}; my_var; ", false},
+ {"", "function my_var() {} my_var;", false},
+ {"", "if (true) { function my_var() {} } my_var;", false},
+ {"", "function inner2() { if (true) { function my_var() {} } my_var; }",
+ false},
+ {"", "() => { if (true) { function my_var() {} } my_var; }", false},
+ {"",
+ "if (true) { var my_var; if (true) { function my_var() {} } } my_var;",
+ false},
+ };
+
+ for (unsigned inner_ix = 0; inner_ix < arraysize(inner_functions);
+ ++inner_ix) {
+ const char* inner_function = inner_functions[inner_ix];
+ int inner_function_len = Utf8LengthHelper(inner_function) - 4;
+
+ for (unsigned i = 0; i < arraysize(inners); ++i) {
+ int params_len = Utf8LengthHelper(inners[i].params);
+ int source_len = Utf8LengthHelper(inners[i].source);
+ int len = prefix_len + inner_function_len + params_len + source_len +
+ suffix_len;
+
+ i::ScopedVector<char> program(len + 1);
+ i::SNPrintF(program, "%s", prefix);
+ i::SNPrintF(program + prefix_len, inner_function, inners[i].params,
+ inners[i].source);
+ i::SNPrintF(
+ program + prefix_len + inner_function_len + params_len + source_len,
+ "%s", suffix);
+
+ i::Handle<i::String> source =
+ factory->InternalizeUtf8String(program.start());
+ source->PrintOn(stdout);
+ printf("\n");
+
+ i::Handle<i::Script> script = factory->NewScript(source);
+ i::Zone zone(isolate->allocator(), ZONE_NAME);
+ i::ParseInfo info(&zone, script);
+
+ CHECK(i::parsing::ParseProgram(&info));
+ CHECK(i::Compiler::Analyze(&info));
+ CHECK(info.literal() != NULL);
+
+ i::Scope* scope = info.literal()->scope()->inner_scope();
+ DCHECK_NOT_NULL(scope);
+ DCHECK_NULL(scope->sibling());
+ DCHECK(scope->is_function_scope());
+ const i::AstRawString* var_name =
+ info.ast_value_factory()->GetOneByteString("my_var");
+ i::Variable* var = scope->Lookup(var_name);
+ CHECK_EQ(inners[i].ctxt_allocate,
+ i::ScopeTestHelper::MustAllocateInContext(var));
+ }
+ }
+}
diff --git a/deps/v8/test/cctest/test-profile-generator.cc b/deps/v8/test/cctest/test-profile-generator.cc
index b7aba6e9da..71728924db 100644
--- a/deps/v8/test/cctest/test-profile-generator.cc
+++ b/deps/v8/test/cctest/test-profile-generator.cc
@@ -29,6 +29,7 @@
#include "include/v8-profiler.h"
#include "src/api.h"
+#include "src/objects-inl.h"
#include "src/profiler/cpu-profiler.h"
#include "src/profiler/profile-generator-inl.h"
#include "src/v8.h"
diff --git a/deps/v8/test/cctest/test-regexp.cc b/deps/v8/test/cctest/test-regexp.cc
index a9d941d998..ee6a6c2ab7 100644
--- a/deps/v8/test/cctest/test-regexp.cc
+++ b/deps/v8/test/cctest/test-regexp.cc
@@ -34,10 +34,11 @@
#include "src/ast/ast.h"
#include "src/char-predicates-inl.h"
+#include "src/objects-inl.h"
#include "src/ostreams.h"
#include "src/regexp/jsregexp.h"
-#include "src/regexp/regexp-macro-assembler.h"
#include "src/regexp/regexp-macro-assembler-irregexp.h"
+#include "src/regexp/regexp-macro-assembler.h"
#include "src/regexp/regexp-parser.h"
#include "src/splay-tree-inl.h"
#include "src/string-stream.h"
diff --git a/deps/v8/test/cctest/test-serialize.cc b/deps/v8/test/cctest/test-serialize.cc
index 1b5497f772..9644d09624 100644
--- a/deps/v8/test/cctest/test-serialize.cc
+++ b/deps/v8/test/cctest/test-serialize.cc
@@ -285,8 +285,9 @@ static void PartiallySerializeObject(Vector<const byte>* startup_blob_out,
isolate, v8::SnapshotCreator::FunctionCodeHandling::kClear);
startup_serializer.SerializeStrongReferences();
- PartialSerializer partial_serializer(isolate, &startup_serializer, nullptr);
- partial_serializer.Serialize(&raw_foo);
+ PartialSerializer partial_serializer(isolate, &startup_serializer,
+ v8::SerializeInternalFieldsCallback());
+ partial_serializer.Serialize(&raw_foo, false);
startup_serializer.SerializeWeakReferencesAndDeferred();
@@ -321,7 +322,9 @@ UNINITIALIZED_TEST(PartialSerializerObject) {
{
SnapshotData snapshot_data(partial_blob);
Deserializer deserializer(&snapshot_data);
- root = deserializer.DeserializePartial(isolate, global_proxy)
+ root = deserializer
+ .DeserializePartial(isolate, global_proxy,
+ v8::DeserializeInternalFieldsCallback())
.ToHandleChecked();
CHECK(root->IsString());
}
@@ -330,7 +333,9 @@ UNINITIALIZED_TEST(PartialSerializerObject) {
{
SnapshotData snapshot_data(partial_blob);
Deserializer deserializer(&snapshot_data);
- root2 = deserializer.DeserializePartial(isolate, global_proxy)
+ root2 = deserializer
+ .DeserializePartial(isolate, global_proxy,
+ v8::DeserializeInternalFieldsCallback())
.ToHandleChecked();
CHECK(root2->IsString());
CHECK(root.is_identical_to(root2));
@@ -385,8 +390,9 @@ static void PartiallySerializeContext(Vector<const byte>* startup_blob_out,
startup_serializer.SerializeStrongReferences();
SnapshotByteSink partial_sink;
- PartialSerializer partial_serializer(isolate, &startup_serializer, nullptr);
- partial_serializer.Serialize(&raw_context);
+ PartialSerializer partial_serializer(isolate, &startup_serializer,
+ v8::SerializeInternalFieldsCallback());
+ partial_serializer.Serialize(&raw_context, false);
startup_serializer.SerializeWeakReferencesAndDeferred();
SnapshotData startup_snapshot(&startup_serializer);
@@ -419,7 +425,9 @@ UNINITIALIZED_TEST(PartialSerializerContext) {
{
SnapshotData snapshot_data(partial_blob);
Deserializer deserializer(&snapshot_data);
- root = deserializer.DeserializePartial(isolate, global_proxy)
+ root = deserializer
+ .DeserializePartial(isolate, global_proxy,
+ v8::DeserializeInternalFieldsCallback())
.ToHandleChecked();
CHECK(root->IsContext());
CHECK(Handle<Context>::cast(root)->global_proxy() == *global_proxy);
@@ -429,7 +437,9 @@ UNINITIALIZED_TEST(PartialSerializerContext) {
{
SnapshotData snapshot_data(partial_blob);
Deserializer deserializer(&snapshot_data);
- root2 = deserializer.DeserializePartial(isolate, global_proxy)
+ root2 = deserializer
+ .DeserializePartial(isolate, global_proxy,
+ v8::DeserializeInternalFieldsCallback())
.ToHandleChecked();
CHECK(root2->IsContext());
CHECK(!root.is_identical_to(root2));
@@ -505,8 +515,9 @@ static void PartiallySerializeCustomContext(
startup_serializer.SerializeStrongReferences();
SnapshotByteSink partial_sink;
- PartialSerializer partial_serializer(isolate, &startup_serializer, nullptr);
- partial_serializer.Serialize(&raw_context);
+ PartialSerializer partial_serializer(isolate, &startup_serializer,
+ v8::SerializeInternalFieldsCallback());
+ partial_serializer.Serialize(&raw_context, false);
startup_serializer.SerializeWeakReferencesAndDeferred();
SnapshotData startup_snapshot(&startup_serializer);
@@ -539,7 +550,9 @@ UNINITIALIZED_TEST(PartialSerializerCustomContext) {
{
SnapshotData snapshot_data(partial_blob);
Deserializer deserializer(&snapshot_data);
- root = deserializer.DeserializePartial(isolate, global_proxy)
+ root = deserializer
+ .DeserializePartial(isolate, global_proxy,
+ v8::DeserializeInternalFieldsCallback())
.ToHandleChecked();
CHECK(root->IsContext());
Handle<Context> context = Handle<Context>::cast(root);
@@ -1075,7 +1088,7 @@ TEST(CodeSerializerLargeCodeObject) {
Vector<const uint8_t> source =
ConstructSource(STATIC_CHAR_VECTOR("var j=1; if (j == 0) {"),
STATIC_CHAR_VECTOR("for (let i of Object.prototype);"),
- STATIC_CHAR_VECTOR("} j=7; j"), 1000);
+ STATIC_CHAR_VECTOR("} j=7; j"), 1050);
Handle<String> source_str =
isolate->factory()->NewStringFromOneByte(source).ToHandleChecked();
@@ -1771,7 +1784,6 @@ TEST(CodeSerializerEagerCompilationAndPreAge) {
FLAG_serialize_toplevel = true;
FLAG_serialize_age_code = true;
FLAG_serialize_eager = true;
- FLAG_min_preparse_length = 1;
static const char* source =
"function f() {"
@@ -1807,10 +1819,10 @@ TEST(CodeSerializerEagerCompilationAndPreAge) {
HandleScope i_scope(i_isolate);
Handle<SharedFunctionInfo> toplevel = v8::Utils::OpenHandle(*unbound);
Handle<Script> script(Script::cast(toplevel->script()));
- WeakFixedArray::Iterator iterator(script->shared_function_infos());
// Every function has been pre-compiled from the code cache.
int count = 0;
- while (SharedFunctionInfo* shared = iterator.Next<SharedFunctionInfo>()) {
+ SharedFunctionInfo::ScriptIterator iterator(script);
+ while (SharedFunctionInfo* shared = iterator.Next()) {
CHECK(shared->is_compiled());
CHECK_EQ(Code::kPreAgedCodeAge, shared->code()->GetAge());
count++;
@@ -1821,6 +1833,7 @@ TEST(CodeSerializerEagerCompilationAndPreAge) {
}
TEST(Regress503552) {
+ if (!FLAG_incremental_marking) return;
// Test that the code serializer can deal with weak cells that form a linked
// list during incremental marking.
CcTest::InitializeVM();
@@ -1962,19 +1975,19 @@ TEST(SnapshotCreatorMultipleContexts) {
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
CompileRun("var f = function() { return 1; }");
- CHECK_EQ(0u, creator.AddContext(context));
+ creator.SetDefaultContext(context);
}
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
CompileRun("var f = function() { return 2; }");
- CHECK_EQ(1u, creator.AddContext(context));
+ CHECK_EQ(0u, creator.AddContext(context));
}
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
- CHECK_EQ(2u, creator.AddContext(context));
+ CHECK_EQ(1u, creator.AddContext(context));
}
blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
@@ -1988,22 +2001,21 @@ TEST(SnapshotCreatorMultipleContexts) {
v8::Isolate::Scope isolate_scope(isolate);
{
v8::HandleScope handle_scope(isolate);
- v8::Local<v8::Context> context =
- v8::Context::FromSnapshot(isolate, 0).ToLocalChecked();
+ v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
ExpectInt32("f()", 1);
}
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context =
- v8::Context::FromSnapshot(isolate, 1).ToLocalChecked();
+ v8::Context::FromSnapshot(isolate, 0).ToLocalChecked();
v8::Context::Scope context_scope(context);
ExpectInt32("f()", 2);
}
{
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context =
- v8::Context::FromSnapshot(isolate, 2).ToLocalChecked();
+ v8::Context::FromSnapshot(isolate, 1).ToLocalChecked();
v8::Context::Scope context_scope(context);
ExpectUndefined("this.f");
}
@@ -2013,24 +2025,68 @@ TEST(SnapshotCreatorMultipleContexts) {
delete[] blob.data;
}
-void SerializedCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {
+static void SerializedCallback(
+ const v8::FunctionCallbackInfo<v8::Value>& args) {
args.GetReturnValue().Set(v8_num(42));
}
-void SerializedCallbackReplacement(
+static void SerializedCallbackReplacement(
const v8::FunctionCallbackInfo<v8::Value>& args) {
args.GetReturnValue().Set(v8_num(1337));
}
+static void NamedPropertyGetterForSerialization(
+ v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
+ if (name->Equals(info.GetIsolate()->GetCurrentContext(), v8_str("x"))
+ .FromJust()) {
+ info.GetReturnValue().Set(v8_num(2016));
+ }
+}
+
+static void AccessorForSerialization(
+ v8::Local<v8::String> property,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ info.GetReturnValue().Set(v8_num(2017));
+}
+
static int serialized_static_field = 314;
+class SerializedExtension : public v8::Extension {
+ public:
+ SerializedExtension()
+ : v8::Extension("serialized extension",
+ "native function g();"
+ "function h() { return 13; };"
+ "function i() { return 14; };"
+ "var o = { p: 7 };") {}
+
+ virtual v8::Local<v8::FunctionTemplate> GetNativeFunctionTemplate(
+ v8::Isolate* isolate, v8::Local<v8::String> name) {
+ CHECK(name->Equals(isolate->GetCurrentContext(), v8_str("g")).FromJust());
+ return v8::FunctionTemplate::New(isolate, FunctionCallback);
+ }
+
+ static void FunctionCallback(
+ const v8::FunctionCallbackInfo<v8::Value>& args) {
+ args.GetReturnValue().Set(v8_num(12));
+ }
+};
+
intptr_t original_external_references[] = {
reinterpret_cast<intptr_t>(SerializedCallback),
- reinterpret_cast<intptr_t>(&serialized_static_field), 0};
+ reinterpret_cast<intptr_t>(&serialized_static_field),
+ reinterpret_cast<intptr_t>(&NamedPropertyGetterForSerialization),
+ reinterpret_cast<intptr_t>(&AccessorForSerialization),
+ reinterpret_cast<intptr_t>(&SerializedExtension::FunctionCallback),
+ 0};
intptr_t replaced_external_references[] = {
reinterpret_cast<intptr_t>(SerializedCallbackReplacement),
- reinterpret_cast<intptr_t>(&serialized_static_field), 0};
+ reinterpret_cast<intptr_t>(&serialized_static_field),
+ reinterpret_cast<intptr_t>(&NamedPropertyGetterForSerialization),
+ reinterpret_cast<intptr_t>(&AccessorForSerialization),
+ reinterpret_cast<intptr_t>(&SerializedExtension::FunctionCallback),
+ 0};
TEST(SnapshotCreatorExternalReferences) {
DisableAlwaysOpt();
@@ -2048,7 +2104,7 @@ TEST(SnapshotCreatorExternalReferences) {
callback->GetFunction(context).ToLocalChecked();
CHECK(context->Global()->Set(context, v8_str("f"), function).FromJust());
ExpectInt32("f()", 42);
- CHECK_EQ(0u, creator.AddContext(context));
+ creator.SetDefaultContext(context);
}
blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
@@ -2064,8 +2120,7 @@ TEST(SnapshotCreatorExternalReferences) {
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
- v8::Local<v8::Context> context =
- v8::Context::FromSnapshot(isolate, 0).ToLocalChecked();
+ v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
ExpectInt32("f()", 42);
}
@@ -2082,8 +2137,7 @@ TEST(SnapshotCreatorExternalReferences) {
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
- v8::Local<v8::Context> context =
- v8::Context::FromSnapshot(isolate, 0).ToLocalChecked();
+ v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
ExpectInt32("f()", 1337);
}
@@ -2108,7 +2162,7 @@ TEST(SnapshotCreatorUnknownExternalReferences) {
CHECK(context->Global()->Set(context, v8_str("f"), function).FromJust());
ExpectInt32("f()", 42);
- CHECK_EQ(0u, creator.AddContext(context));
+ creator.SetDefaultContext(context);
}
v8::StartupData blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
@@ -2120,22 +2174,27 @@ struct InternalFieldData {
uint32_t data;
};
-v8::StartupData SerializeInternalFields(v8::Local<v8::Object> holder,
- int index) {
- InternalFieldData* data = static_cast<InternalFieldData*>(
+v8::StartupData SerializeInternalFields(v8::Local<v8::Object> holder, int index,
+ void* data) {
+ CHECK_EQ(reinterpret_cast<void*>(2016), data);
+ InternalFieldData* internal_field = static_cast<InternalFieldData*>(
holder->GetAlignedPointerFromInternalField(index));
- int size = sizeof(*data);
+ int size = sizeof(*internal_field);
char* payload = new char[size];
// We simply use memcpy to serialize the content.
- memcpy(payload, data, size);
+ memcpy(payload, internal_field, size);
return {payload, size};
}
+std::vector<InternalFieldData*> deserialized_data;
+
void DeserializeInternalFields(v8::Local<v8::Object> holder, int index,
- v8::StartupData payload) {
- InternalFieldData* data = new InternalFieldData{0};
- memcpy(data, payload.data, payload.raw_size);
- holder->SetAlignedPointerInInternalField(index, data);
+ v8::StartupData payload, void* data) {
+ CHECK_EQ(reinterpret_cast<void*>(2017), data);
+ InternalFieldData* internal_field = new InternalFieldData{0};
+ memcpy(internal_field, payload.data, payload.raw_size);
+ holder->SetAlignedPointerInInternalField(index, internal_field);
+ deserialized_data.push_back(internal_field);
}
TEST(SnapshotCreatorTemplates) {
@@ -2159,6 +2218,8 @@ TEST(SnapshotCreatorTemplates) {
global_template->Set(v8_str("f"), callback);
v8::Local<v8::Context> context =
v8::Context::New(isolate, no_extension, global_template);
+ creator.SetDefaultContext(context);
+ context = v8::Context::New(isolate, no_extension, global_template);
v8::Local<v8::ObjectTemplate> object_template =
v8::ObjectTemplate::New(isolate);
object_template->SetInternalFieldCount(3);
@@ -2185,12 +2246,15 @@ TEST(SnapshotCreatorTemplates) {
c->SetInternalField(2, field_external);
CHECK(context->Global()->Set(context, v8_str("a"), a).FromJust());
- CHECK_EQ(0u, creator.AddContext(context));
+ CHECK_EQ(0u,
+ creator.AddContext(context, v8::SerializeInternalFieldsCallback(
+ SerializeInternalFields,
+ reinterpret_cast<void*>(2016))));
CHECK_EQ(0u, creator.AddTemplate(callback));
CHECK_EQ(1u, creator.AddTemplate(global_template));
}
- blob = creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear,
- SerializeInternalFields);
+ blob =
+ creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
delete a1;
delete b0;
@@ -2202,7 +2266,6 @@ TEST(SnapshotCreatorTemplates) {
params.snapshot_blob = &blob;
params.array_buffer_allocator = CcTest::array_buffer_allocator();
params.external_references = original_external_references;
- params.deserialize_internal_fields_callback = DeserializeInternalFields;
v8::Isolate* isolate = v8::Isolate::New(params);
{
v8::Isolate::Scope isolate_scope(isolate);
@@ -2210,7 +2273,11 @@ TEST(SnapshotCreatorTemplates) {
// Create a new context without a new object template.
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context =
- v8::Context::FromSnapshot(isolate, 0).ToLocalChecked();
+ v8::Context::FromSnapshot(
+ isolate, 0,
+ v8::DeserializeInternalFieldsCallback(
+ DeserializeInternalFields, reinterpret_cast<void*>(2017)))
+ .ToLocalChecked();
v8::Context::Scope context_scope(context);
ExpectInt32("f()", 42);
@@ -2272,29 +2339,208 @@ TEST(SnapshotCreatorTemplates) {
// Accessing out of bound returns empty MaybeHandle.
CHECK(v8::ObjectTemplate::FromSnapshot(isolate, 2).IsEmpty());
CHECK(v8::FunctionTemplate::FromSnapshot(isolate, 2).IsEmpty());
- CHECK(v8::Context::FromSnapshot(isolate, 2).IsEmpty());
+ CHECK(v8::Context::FromSnapshot(isolate, 1).IsEmpty());
- delete a1;
- delete b0;
- delete c0;
+ for (auto data : deserialized_data) delete data;
+ deserialized_data.clear();
}
+ }
+ isolate->Dispose();
+ }
+ delete[] blob.data;
+}
+
+TEST(SnapshotCreatorIncludeGlobalProxy) {
+ DisableAlwaysOpt();
+ v8::StartupData blob;
+
+ {
+ v8::SnapshotCreator creator(original_external_references);
+ v8::Isolate* isolate = creator.GetIsolate();
+ v8::RegisterExtension(new SerializedExtension);
+ const char* extension_names[] = {"serialized extension"};
+ v8::ExtensionConfiguration extensions(1, extension_names);
+ {
+ // Set default context. This context implicitly does *not* serialize
+ // the global proxy, and upon deserialization one has to be created
+ // in the bootstrapper from the global object template.
+ // Side effects from extensions are persisted though.
+ v8::HandleScope handle_scope(isolate);
+ v8::Local<v8::ObjectTemplate> global_template =
+ v8::ObjectTemplate::New(isolate);
+ v8::Local<v8::FunctionTemplate> callback =
+ v8::FunctionTemplate::New(isolate, SerializedCallback);
+ global_template->Set(v8_str("f"), callback);
+ global_template->SetHandler(v8::NamedPropertyHandlerConfiguration(
+ NamedPropertyGetterForSerialization));
+ v8::Local<v8::Context> context =
+ v8::Context::New(isolate, &extensions, global_template);
+ v8::Context::Scope context_scope(context);
+ ExpectInt32("f()", 42);
+ ExpectInt32("g()", 12);
+ ExpectInt32("h()", 13);
+ ExpectInt32("o.p", 7);
+ ExpectInt32("x", 2016);
+ creator.SetDefaultContext(context);
+ }
+ {
+ // Add additional context. This context implicitly *does* serialize
+ // the global proxy, and upon deserialization one has to be created
+ // in the bootstrapper from the global object template.
+ // Side effects from extensions are persisted.
+ v8::HandleScope handle_scope(isolate);
+ v8::Local<v8::ObjectTemplate> global_template =
+ v8::ObjectTemplate::New(isolate);
+ v8::Local<v8::FunctionTemplate> callback =
+ v8::FunctionTemplate::New(isolate, SerializedCallback);
+ global_template->SetInternalFieldCount(3);
+ global_template->Set(v8_str("f"), callback);
+ global_template->SetHandler(v8::NamedPropertyHandlerConfiguration(
+ NamedPropertyGetterForSerialization));
+ global_template->SetAccessor(v8_str("y"), AccessorForSerialization);
+ v8::Local<v8::Private> priv =
+ v8::Private::ForApi(isolate, v8_str("cached"));
+ global_template->SetAccessorProperty(
+ v8_str("cached"),
+ v8::FunctionTemplate::NewWithCache(isolate, SerializedCallback, priv,
+ v8::Local<v8::Value>()));
+ v8::Local<v8::Context> context =
+ v8::Context::New(isolate, &extensions, global_template);
+ v8::Context::Scope context_scope(context);
+
+ CHECK(context->Global()
+ ->SetPrivate(context, priv, v8_str("cached string"))
+ .FromJust());
+ v8::Local<v8::Private> hidden =
+ v8::Private::ForApi(isolate, v8_str("hidden"));
+ CHECK(context->Global()
+ ->SetPrivate(context, hidden, v8_str("hidden string"))
+ .FromJust());
+ ExpectInt32("f()", 42);
+ ExpectInt32("g()", 12);
+ ExpectInt32("h()", 13);
+ ExpectInt32("o.p", 7);
+ ExpectInt32("x", 2016);
+ ExpectInt32("y", 2017);
+ CHECK(v8_str("hidden string")
+ ->Equals(context, context->Global()
+ ->GetPrivate(context, hidden)
+ .ToLocalChecked())
+ .FromJust());
+
+ CHECK_EQ(0u,
+ creator.AddContext(context, v8::SerializeInternalFieldsCallback(
+ SerializeInternalFields,
+ reinterpret_cast<void*>(2016))));
+ }
+ blob =
+ creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
+ }
+
+ {
+ v8::Isolate::CreateParams params;
+ params.snapshot_blob = &blob;
+ params.array_buffer_allocator = CcTest::array_buffer_allocator();
+ params.external_references = original_external_references;
+ v8::Isolate* isolate = v8::Isolate::New(params);
+ {
+ v8::Isolate::Scope isolate_scope(isolate);
+ // We can introduce new extensions, which could override the already
+ // snapshotted extension.
+ v8::Extension* extension = new v8::Extension("new extension",
+ "function i() { return 24; }"
+ "function j() { return 25; }"
+ "if (o.p == 7) o.p++;");
+ extension->set_auto_enable(true);
+ v8::RegisterExtension(extension);
{
- // Create a context with a new object template. It is merged into the
- // deserialized global object.
+ // Create a new context from default context snapshot. This will
+ // create a new global object from a new global object template
+ // without the interceptor.
v8::HandleScope handle_scope(isolate);
- v8::ExtensionConfiguration* no_extension = nullptr;
- v8::Local<v8::ObjectTemplate> global_template =
- v8::ObjectTemplate::New(isolate);
- global_template->Set(
- v8_str("g"),
- v8::FunctionTemplate::New(isolate, SerializedCallbackReplacement));
- v8::Local<v8::Context> context =
- v8::Context::FromSnapshot(isolate, 0, no_extension, global_template)
- .ToLocalChecked();
+ v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
- ExpectInt32("g()", 1337);
ExpectInt32("f()", 42);
+ ExpectInt32("g()", 12);
+ ExpectInt32("h()", 13);
+ ExpectInt32("i()", 24);
+ ExpectInt32("j()", 25);
+ ExpectInt32("o.p", 8);
+ v8::TryCatch try_catch(isolate);
+ CHECK(CompileRun("x").IsEmpty());
+ CHECK(try_catch.HasCaught());
+ }
+ {
+ // Create a new context from first additional context snapshot. This
+ // will use the global object from the snapshot, including interceptor.
+ v8::HandleScope handle_scope(isolate);
+ v8::Local<v8::Context> context =
+ v8::Context::FromSnapshot(
+ isolate, 0,
+ v8::DeserializeInternalFieldsCallback(
+ DeserializeInternalFields, reinterpret_cast<void*>(2017)))
+ .ToLocalChecked();
+
+ {
+ v8::Context::Scope context_scope(context);
+ ExpectInt32("f()", 42);
+ ExpectInt32("g()", 12);
+ ExpectInt32("h()", 13);
+ ExpectInt32("i()", 24);
+ ExpectInt32("j()", 25);
+ ExpectInt32("o.p", 8);
+ ExpectInt32("x", 2016);
+ v8::Local<v8::Private> hidden =
+ v8::Private::ForApi(isolate, v8_str("hidden"));
+ CHECK(v8_str("hidden string")
+ ->Equals(context, context->Global()
+ ->GetPrivate(context, hidden)
+ .ToLocalChecked())
+ .FromJust());
+ ExpectString("cached", "cached string");
+ }
+
+ v8::Local<v8::Object> global = context->Global();
+ CHECK_EQ(3, global->InternalFieldCount());
+ context->DetachGlobal();
+
+ // New context, but reuse global proxy.
+ v8::ExtensionConfiguration* no_extensions = nullptr;
+ v8::Local<v8::Context> context2 =
+ v8::Context::FromSnapshot(
+ isolate, 0,
+ v8::DeserializeInternalFieldsCallback(
+ DeserializeInternalFields, reinterpret_cast<void*>(2017)),
+ no_extensions, global)
+ .ToLocalChecked();
+ {
+ v8::Context::Scope context_scope(context2);
+ ExpectInt32("f()", 42);
+ ExpectInt32("g()", 12);
+ ExpectInt32("h()", 13);
+ ExpectInt32("i()", 24);
+ ExpectInt32("j()", 25);
+ ExpectInt32("o.p", 8);
+ ExpectInt32("x", 2016);
+ v8::Local<v8::Private> hidden =
+ v8::Private::ForApi(isolate, v8_str("hidden"));
+ CHECK(v8_str("hidden string")
+ ->Equals(context2, context2->Global()
+ ->GetPrivate(context2, hidden)
+ .ToLocalChecked())
+ .FromJust());
+
+ // Set cached accessor property again.
+ v8::Local<v8::Private> priv =
+ v8::Private::ForApi(isolate, v8_str("cached"));
+ CHECK(context2->Global()
+ ->SetPrivate(context2, priv, v8_str("cached string 1"))
+ .FromJust());
+ ExpectString("cached", "cached string 1");
+ }
+
+ CHECK(context2->Global()->Equals(context2, global).FromJust());
}
}
isolate->Dispose();
diff --git a/deps/v8/test/cctest/test-strings.cc b/deps/v8/test/cctest/test-strings.cc
index 80c8f92ac4..d7b51f8274 100644
--- a/deps/v8/test/cctest/test-strings.cc
+++ b/deps/v8/test/cctest/test-strings.cc
@@ -37,6 +37,7 @@
#include "src/api.h"
#include "src/factory.h"
#include "src/messages.h"
+#include "src/objects-inl.h"
#include "src/objects.h"
#include "src/unicode-decoder.h"
#include "test/cctest/cctest.h"
@@ -1608,3 +1609,38 @@ TEST(Regress609831) {
CHECK(v8::Utils::OpenHandle(*result)->IsSeqTwoByteString());
}
}
+
+TEST(ExternalStringIndexOf) {
+ CcTest::InitializeVM();
+ LocalContext context;
+ v8::HandleScope scope(CcTest::isolate());
+
+ const char* raw_string = "abcdefghijklmnopqrstuvwxyz";
+ v8::Local<v8::String> string =
+ v8::String::NewExternalOneByte(CcTest::isolate(),
+ new StaticOneByteResource(raw_string))
+ .ToLocalChecked();
+ v8::Local<v8::Object> global = context->Global();
+ global->Set(context.local(), v8_str("external"), string).FromJust();
+
+ char source[] = "external.indexOf('%')";
+ for (size_t i = 0; i < strlen(raw_string); i++) {
+ source[18] = raw_string[i];
+ int result_position = static_cast<int>(i);
+ CHECK_EQ(result_position,
+ CompileRun(source)->Int32Value(context.local()).FromJust());
+ }
+ CHECK_EQ(-1,
+ CompileRun("external.indexOf('abcdefghijklmnopqrstuvwxyz%%%%%%')")
+ ->Int32Value(context.local())
+ .FromJust());
+ CHECK_EQ(1, CompileRun("external.indexOf('', 1)")
+ ->Int32Value(context.local())
+ .FromJust());
+ CHECK_EQ(-1, CompileRun("external.indexOf('a', 1)")
+ ->Int32Value(context.local())
+ .FromJust());
+ CHECK_EQ(-1, CompileRun("external.indexOf('$')")
+ ->Int32Value(context.local())
+ .FromJust());
+}
diff --git a/deps/v8/test/cctest/test-thread-termination.cc b/deps/v8/test/cctest/test-thread-termination.cc
index 523704ba69..d288eb7242 100644
--- a/deps/v8/test/cctest/test-thread-termination.cc
+++ b/deps/v8/test/cctest/test-thread-termination.cc
@@ -27,6 +27,7 @@
#include "src/api.h"
#include "src/isolate.h"
+#include "src/objects-inl.h"
#include "src/v8.h"
#include "test/cctest/cctest.h"
@@ -529,9 +530,11 @@ void InnerTryCallTerminate(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Local<v8::Function> loop = v8::Local<v8::Function>::Cast(
global->Get(CcTest::isolate()->GetCurrentContext(), v8_str("loop"))
.ToLocalChecked());
+ i::MaybeHandle<i::Object> exception;
i::MaybeHandle<i::Object> result =
i::Execution::TryCall(CcTest::i_isolate(), v8::Utils::OpenHandle((*loop)),
- v8::Utils::OpenHandle((*global)), 0, NULL, NULL);
+ v8::Utils::OpenHandle((*global)), 0, nullptr,
+ i::Execution::MessageHandling::kReport, &exception);
CHECK(result.is_null());
// TryCall ignores terminate execution, but rerequests the interrupt.
CHECK(!args.GetIsolate()->IsExecutionTerminating());
diff --git a/deps/v8/test/cctest/test-transitions.cc b/deps/v8/test/cctest/test-transitions.cc
index 2f00900057..842a6ca47f 100644
--- a/deps/v8/test/cctest/test-transitions.cc
+++ b/deps/v8/test/cctest/test-transitions.cc
@@ -25,25 +25,6 @@ using namespace v8::internal;
// Helper functions.
//
-static void CheckPropertyDetailsFieldsConsistency(PropertyType type,
- PropertyKind kind,
- PropertyLocation location) {
- int type_value = PropertyDetails::TypeField::encode(type);
- int kind_location_value = PropertyDetails::KindField::encode(kind) |
- PropertyDetails::LocationField::encode(location);
- CHECK_EQ(type_value, kind_location_value);
-}
-
-
-TEST(PropertyDetailsFieldsConsistency) {
- CheckPropertyDetailsFieldsConsistency(DATA, kData, kField);
- CheckPropertyDetailsFieldsConsistency(DATA_CONSTANT, kData, kDescriptor);
- CheckPropertyDetailsFieldsConsistency(ACCESSOR, kAccessor, kField);
- CheckPropertyDetailsFieldsConsistency(ACCESSOR_CONSTANT, kAccessor,
- kDescriptor);
-}
-
-
TEST(TransitionArray_SimpleFieldTransitions) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
diff --git a/deps/v8/test/cctest/test-typedarrays.cc b/deps/v8/test/cctest/test-typedarrays.cc
index 348eb05a3a..10b20acfa1 100644
--- a/deps/v8/test/cctest/test-typedarrays.cc
+++ b/deps/v8/test/cctest/test-typedarrays.cc
@@ -9,6 +9,7 @@
#include "src/api.h"
#include "src/heap/heap.h"
+#include "src/objects-inl.h"
#include "src/objects.h"
using namespace v8::internal;
diff --git a/deps/v8/test/cctest/test-unboxed-doubles.cc b/deps/v8/test/cctest/test-unboxed-doubles.cc
index abaa058f85..582e2757fb 100644
--- a/deps/v8/test/cctest/test-unboxed-doubles.cc
+++ b/deps/v8/test/cctest/test-unboxed-doubles.cc
@@ -106,13 +106,14 @@ static Handle<DescriptorArray> CreateDescriptorArray(Isolate* isolate,
TestPropertyKind kind = props[i];
if (kind == PROP_CONSTANT) {
- DataConstantDescriptor d(name, func, NONE);
+ Descriptor d = Descriptor::DataConstant(name, func, NONE);
descriptors->Append(&d);
} else {
- DataDescriptor f(name, next_field_offset, NONE, representations[kind]);
- next_field_offset += f.GetDetails().field_width_in_words();
- descriptors->Append(&f);
+ Descriptor d = Descriptor::DataField(name, next_field_offset, NONE,
+ representations[kind]);
+ next_field_offset += d.GetDetails().field_width_in_words();
+ descriptors->Append(&d);
}
}
return descriptors;
@@ -628,18 +629,19 @@ static Handle<LayoutDescriptor> TestLayoutDescriptorAppend(
Handle<LayoutDescriptor> layout_descriptor;
TestPropertyKind kind = props[i];
if (kind == PROP_CONSTANT) {
- DataConstantDescriptor d(name, func, NONE);
+ Descriptor d = Descriptor::DataConstant(name, func, NONE);
layout_descriptor = LayoutDescriptor::ShareAppend(map, d.GetDetails());
descriptors->Append(&d);
} else {
- DataDescriptor f(name, next_field_offset, NONE, representations[kind]);
- int field_width_in_words = f.GetDetails().field_width_in_words();
+ Descriptor d = Descriptor::DataField(name, next_field_offset, NONE,
+ representations[kind]);
+ int field_width_in_words = d.GetDetails().field_width_in_words();
next_field_offset += field_width_in_words;
- layout_descriptor = LayoutDescriptor::ShareAppend(map, f.GetDetails());
- descriptors->Append(&f);
+ layout_descriptor = LayoutDescriptor::ShareAppend(map, d.GetDetails());
+ descriptors->Append(&d);
- int field_index = f.GetDetails().field_index();
+ int field_index = d.GetDetails().field_index();
bool is_inobject = field_index < map->GetInObjectProperties();
for (int bit = 0; bit < field_width_in_words; bit++) {
CHECK_EQ(is_inobject && (kind == PROP_DOUBLE),
@@ -783,7 +785,7 @@ static Handle<LayoutDescriptor> TestLayoutDescriptorAppendIfFastOrUseFull(
CHECK_EQ(*full_layout_descriptor, layout_desc);
} else {
CHECK(!switched_to_slow_mode);
- if (details.type() == DATA) {
+ if (details.location() == kField) {
nof++;
int field_index = details.field_index();
int field_width_in_words = details.field_width_in_words();
@@ -1191,7 +1193,7 @@ static void TestLayoutDescriptorHelper(Isolate* isolate,
int first_non_tagged_field_offset = end_offset;
for (int i = 0; i < number_of_descriptors; i++) {
PropertyDetails details = descriptors->GetDetails(i);
- if (details.type() != DATA) continue;
+ if (details.location() != kField) continue;
FieldIndex index = FieldIndex::ForDescriptor(*map, i);
if (!index.is_inobject()) continue;
all_fields_tagged &= !details.representation().IsDouble();
@@ -1532,7 +1534,7 @@ static void TestWriteBarrierObjectShiftFieldsRight(
// Shift fields right by turning constant property to a field.
Handle<Map> new_map = Map::ReconfigureProperty(
- map, 0, kData, NONE, Representation::Tagged(), any_type, FORCE_FIELD);
+ map, 0, kData, NONE, Representation::Tagged(), any_type);
if (write_barrier_kind == OLD_TO_NEW_WRITE_BARRIER) {
TestWriteBarrier(map, new_map, 2, 1);
diff --git a/deps/v8/test/cctest/test-usecounters.cc b/deps/v8/test/cctest/test-usecounters.cc
index 8d4628c9f7..3482476b76 100644
--- a/deps/v8/test/cctest/test-usecounters.cc
+++ b/deps/v8/test/cctest/test-usecounters.cc
@@ -71,3 +71,46 @@ TEST(DefineGetterSetterThrowUseCount) {
"a.__defineSetter__('b', ()=>{});");
CHECK_EQ(2, use_counts[v8::Isolate::kDefineGetterOrSetterWouldThrow]);
}
+
+TEST(AssigmentExpressionLHSIsCall) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ LocalContext env;
+ int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
+ global_use_counts = use_counts;
+ CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
+
+ // AssignmentExpressions whose LHS is not a call do not increment counters
+ CompileRun("function f(){ a = 0; a()[b] = 0; }");
+ CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]);
+ CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]);
+ CompileRun("function f(){ ++a; ++a()[b]; }");
+ CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]);
+ CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]);
+ CompileRun("function f(){ 'use strict'; a = 0; a()[b] = 0; }");
+ CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]);
+ CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]);
+ CompileRun("function f(){ 'use strict'; ++a; ++a()[b]; }");
+ CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]);
+ CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]);
+
+ // AssignmentExpressions whose LHS is a call increment appropriate counters
+ CompileRun("function f(){ a() = 0; }");
+ CHECK_NE(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]);
+ CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]);
+ use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy] = 0;
+ CompileRun("function f(){ 'use strict'; a() = 0; }");
+ CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]);
+ CHECK_NE(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]);
+ use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict] = 0;
+
+ // UpdateExpressions whose LHS is a call increment appropriate counters
+ CompileRun("function f(){ ++a(); }");
+ CHECK_NE(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]);
+ CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]);
+ use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy] = 0;
+ CompileRun("function f(){ 'use strict'; ++a(); }");
+ CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]);
+ CHECK_NE(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]);
+ use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict] = 0;
+}
diff --git a/deps/v8/test/cctest/test-weakmaps.cc b/deps/v8/test/cctest/test-weakmaps.cc
index eb5333f6c0..0aee37bb5a 100644
--- a/deps/v8/test/cctest/test-weakmaps.cc
+++ b/deps/v8/test/cctest/test-weakmaps.cc
@@ -249,6 +249,7 @@ TEST(Regress2060b) {
TEST(Regress399527) {
+ if (!FLAG_incremental_marking) return;
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
diff --git a/deps/v8/test/cctest/wasm/OWNERS b/deps/v8/test/cctest/wasm/OWNERS
index eda8deabfd..59b1e7dc7a 100644
--- a/deps/v8/test/cctest/wasm/OWNERS
+++ b/deps/v8/test/cctest/wasm/OWNERS
@@ -1,5 +1,6 @@
ahaas@chromium.org
bradnelson@chromium.org
+clemensh@chromium.org
mtrofin@chromium.org
rossberg@chromium.org
titzer@chromium.org
diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-64.cc b/deps/v8/test/cctest/wasm/test-run-wasm-64.cc
index e9a2d2da47..4571364980 100644
--- a/deps/v8/test/cctest/wasm/test-run-wasm-64.cc
+++ b/deps/v8/test/cctest/wasm/test-run-wasm-64.cc
@@ -120,7 +120,7 @@ WASM_EXEC_TEST(I64Const_many) {
WASM_EXEC_TEST(Return_I64) {
REQUIRE(I64Return);
- WasmRunner<int64_t> r(execution_mode, MachineType::Int64());
+ WasmRunner<int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_RETURN1(WASM_GET_LOCAL(0)));
@@ -129,29 +129,51 @@ WASM_EXEC_TEST(Return_I64) {
WASM_EXEC_TEST(I64Add) {
REQUIRE(I64Add);
- WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int64_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_INT64_INPUTS(i) {
FOR_INT64_INPUTS(j) { CHECK_EQ(*i + *j, r.Call(*i, *j)); }
}
}
+// The i64 add and subtract regression tests need a 64-bit value with a non-zero
+// upper half. This upper half was clobbering eax, leading to the function
+// returning 1 rather than 0.
+const int64_t kHasBit33On = 0x100000000;
+
+WASM_EXEC_TEST(Regress5800_Add) {
+ REQUIRE(I64Add);
+ WasmRunner<int32_t> r(execution_mode);
+ BUILD(r, WASM_BLOCK(WASM_BR_IF(0, WASM_I64_EQZ(WASM_I64_ADD(
+ WASM_I64V(0), WASM_I64V(kHasBit33On)))),
+ WASM_RETURN1(WASM_I32V(0))),
+ WASM_I32V(0));
+ CHECK_EQ(0, r.Call());
+}
+
WASM_EXEC_TEST(I64Sub) {
REQUIRE(I64Sub);
- WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int64_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_INT64_INPUTS(i) {
FOR_INT64_INPUTS(j) { CHECK_EQ(*i - *j, r.Call(*i, *j)); }
}
}
+WASM_EXEC_TEST(Regress5800_Sub) {
+ REQUIRE(I64Sub);
+ WasmRunner<int32_t> r(execution_mode);
+ BUILD(r, WASM_BLOCK(WASM_BR_IF(0, WASM_I64_EQZ(WASM_I64_SUB(
+ WASM_I64V(0), WASM_I64V(kHasBit33On)))),
+ WASM_RETURN1(WASM_I32V(0))),
+ WASM_I32V(0));
+ CHECK_EQ(0, r.Call());
+}
+
WASM_EXEC_TEST(I64AddUseOnlyLowWord) {
REQUIRE(I64Add);
REQUIRE(I32ConvertI64);
- WasmRunner<int32_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int32_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I32_CONVERT_I64(
WASM_I64_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))));
FOR_INT64_INPUTS(i) {
@@ -164,8 +186,7 @@ WASM_EXEC_TEST(I64AddUseOnlyLowWord) {
WASM_EXEC_TEST(I64SubUseOnlyLowWord) {
REQUIRE(I64Sub);
REQUIRE(I32ConvertI64);
- WasmRunner<int32_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int32_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I32_CONVERT_I64(
WASM_I64_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))));
FOR_INT64_INPUTS(i) {
@@ -178,8 +199,7 @@ WASM_EXEC_TEST(I64SubUseOnlyLowWord) {
WASM_EXEC_TEST(I64MulUseOnlyLowWord) {
REQUIRE(I64Mul);
REQUIRE(I32ConvertI64);
- WasmRunner<int32_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int32_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I32_CONVERT_I64(
WASM_I64_MUL(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))));
FOR_INT64_INPUTS(i) {
@@ -192,8 +212,7 @@ WASM_EXEC_TEST(I64MulUseOnlyLowWord) {
WASM_EXEC_TEST(I64ShlUseOnlyLowWord) {
REQUIRE(I64Shl);
REQUIRE(I32ConvertI64);
- WasmRunner<int32_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int32_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I32_CONVERT_I64(
WASM_I64_SHL(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))));
FOR_INT64_INPUTS(i) {
@@ -207,8 +226,7 @@ WASM_EXEC_TEST(I64ShlUseOnlyLowWord) {
WASM_EXEC_TEST(I64ShrUseOnlyLowWord) {
REQUIRE(I64ShrU);
REQUIRE(I32ConvertI64);
- WasmRunner<int32_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int32_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I32_CONVERT_I64(
WASM_I64_SHR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))));
FOR_UINT64_INPUTS(i) {
@@ -222,8 +240,7 @@ WASM_EXEC_TEST(I64ShrUseOnlyLowWord) {
WASM_EXEC_TEST(I64SarUseOnlyLowWord) {
REQUIRE(I64ShrS);
REQUIRE(I32ConvertI64);
- WasmRunner<int32_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int32_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I32_CONVERT_I64(
WASM_I64_SAR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))));
FOR_INT64_INPUTS(i) {
@@ -234,10 +251,9 @@ WASM_EXEC_TEST(I64SarUseOnlyLowWord) {
}
}
-WASM_EXEC_TEST(I64DivS) {
+WASM_EXEC_TEST_WITH_TRAP(I64DivS) {
REQUIRE(I64DivS);
- WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int64_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_DIVS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_INT64_INPUTS(i) {
FOR_INT64_INPUTS(j) {
@@ -252,10 +268,9 @@ WASM_EXEC_TEST(I64DivS) {
}
}
-WASM_EXEC_TEST(I64DivS_Trap) {
+WASM_EXEC_TEST_WITH_TRAP(I64DivS_Trap) {
REQUIRE(I64DivS);
- WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int64_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_DIVS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
CHECK_EQ(0, r.Call(asi64(0), asi64(100)));
CHECK_TRAP64(r.Call(asi64(100), asi64(0)));
@@ -264,10 +279,10 @@ WASM_EXEC_TEST(I64DivS_Trap) {
CHECK_TRAP64(r.Call(std::numeric_limits<int64_t>::min(), asi64(0)));
}
-WASM_EXEC_TEST(I64DivS_Byzero_Const) {
+WASM_EXEC_TEST_WITH_TRAP(I64DivS_Byzero_Const) {
REQUIRE(I64DivS);
for (int8_t denom = -2; denom < 8; denom++) {
- WasmRunner<int64_t> r(execution_mode, MachineType::Int64());
+ WasmRunner<int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_DIVS(WASM_GET_LOCAL(0), WASM_I64V_1(denom)));
for (int64_t val = -7; val < 8; val++) {
if (denom == 0) {
@@ -279,10 +294,9 @@ WASM_EXEC_TEST(I64DivS_Byzero_Const) {
}
}
-WASM_EXEC_TEST(I64DivU) {
+WASM_EXEC_TEST_WITH_TRAP(I64DivU) {
REQUIRE(I64DivU);
- WasmRunner<uint64_t> r(execution_mode, MachineType::Uint64(),
- MachineType::Uint64());
+ WasmRunner<uint64_t, uint64_t, uint64_t> r(execution_mode);
BUILD(r, WASM_I64_DIVU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_UINT64_INPUTS(i) {
FOR_UINT64_INPUTS(j) {
@@ -295,21 +309,20 @@ WASM_EXEC_TEST(I64DivU) {
}
}
-WASM_EXEC_TEST(I64DivU_Trap) {
+WASM_EXEC_TEST_WITH_TRAP(I64DivU_Trap) {
REQUIRE(I64DivU);
- WasmRunner<uint64_t> r(execution_mode, MachineType::Uint64(),
- MachineType::Uint64());
+ WasmRunner<uint64_t, uint64_t, uint64_t> r(execution_mode);
BUILD(r, WASM_I64_DIVU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
- CHECK_EQ(0u, r.Call(asu64(0), asu64(100)));
+ CHECK_EQ(0, r.Call(asu64(0), asu64(100)));
CHECK_TRAP64(r.Call(asu64(100), asu64(0)));
CHECK_TRAP64(r.Call(asu64(1001), asu64(0)));
CHECK_TRAP64(r.Call(std::numeric_limits<uint64_t>::max(), asu64(0)));
}
-WASM_EXEC_TEST(I64DivU_Byzero_Const) {
+WASM_EXEC_TEST_WITH_TRAP(I64DivU_Byzero_Const) {
REQUIRE(I64DivU);
for (uint64_t denom = 0xfffffffffffffffe; denom < 8; denom++) {
- WasmRunner<uint64_t> r(execution_mode, MachineType::Uint64());
+ WasmRunner<uint64_t, uint64_t> r(execution_mode);
BUILD(r, WASM_I64_DIVU(WASM_GET_LOCAL(0), WASM_I64V_1(denom)));
for (uint64_t val = 0xfffffffffffffff0; val < 8; val++) {
@@ -322,10 +335,9 @@ WASM_EXEC_TEST(I64DivU_Byzero_Const) {
}
}
-WASM_EXEC_TEST(I64RemS) {
+WASM_EXEC_TEST_WITH_TRAP(I64RemS) {
REQUIRE(I64RemS);
- WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int64_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_REMS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_INT64_INPUTS(i) {
FOR_INT64_INPUTS(j) {
@@ -338,10 +350,9 @@ WASM_EXEC_TEST(I64RemS) {
}
}
-WASM_EXEC_TEST(I64RemS_Trap) {
+WASM_EXEC_TEST_WITH_TRAP(I64RemS_Trap) {
REQUIRE(I64RemS);
- WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int64_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_REMS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
CHECK_EQ(33, r.Call(asi64(133), asi64(100)));
CHECK_EQ(0, r.Call(std::numeric_limits<int64_t>::min(), asi64(-1)));
@@ -350,10 +361,9 @@ WASM_EXEC_TEST(I64RemS_Trap) {
CHECK_TRAP64(r.Call(std::numeric_limits<int64_t>::min(), asi64(0)));
}
-WASM_EXEC_TEST(I64RemU) {
+WASM_EXEC_TEST_WITH_TRAP(I64RemU) {
REQUIRE(I64RemU);
- WasmRunner<uint64_t> r(execution_mode, MachineType::Uint64(),
- MachineType::Uint64());
+ WasmRunner<uint64_t, uint64_t, uint64_t> r(execution_mode);
BUILD(r, WASM_I64_REMU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_UINT64_INPUTS(i) {
FOR_UINT64_INPUTS(j) {
@@ -366,12 +376,11 @@ WASM_EXEC_TEST(I64RemU) {
}
}
-WASM_EXEC_TEST(I64RemU_Trap) {
+WASM_EXEC_TEST_WITH_TRAP(I64RemU_Trap) {
REQUIRE(I64RemU);
- WasmRunner<uint64_t> r(execution_mode, MachineType::Uint64(),
- MachineType::Uint64());
+ WasmRunner<uint64_t, uint64_t, uint64_t> r(execution_mode);
BUILD(r, WASM_I64_REMU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
- CHECK_EQ(17u, r.Call(asu64(217), asu64(100)));
+ CHECK_EQ(17, r.Call(asu64(217), asu64(100)));
CHECK_TRAP64(r.Call(asu64(100), asu64(0)));
CHECK_TRAP64(r.Call(asu64(1001), asu64(0)));
CHECK_TRAP64(r.Call(std::numeric_limits<uint64_t>::max(), asu64(0)));
@@ -379,8 +388,7 @@ WASM_EXEC_TEST(I64RemU_Trap) {
WASM_EXEC_TEST(I64And) {
REQUIRE(I64And);
- WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int64_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_AND(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_INT64_INPUTS(i) {
FOR_INT64_INPUTS(j) { CHECK_EQ((*i) & (*j), r.Call(*i, *j)); }
@@ -389,8 +397,7 @@ WASM_EXEC_TEST(I64And) {
WASM_EXEC_TEST(I64Ior) {
REQUIRE(I64Ior);
- WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int64_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_IOR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_INT64_INPUTS(i) {
FOR_INT64_INPUTS(j) { CHECK_EQ((*i) | (*j), r.Call(*i, *j)); }
@@ -399,8 +406,7 @@ WASM_EXEC_TEST(I64Ior) {
WASM_EXEC_TEST(I64Xor) {
REQUIRE(I64Xor);
- WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int64_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_XOR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_INT64_INPUTS(i) {
FOR_INT64_INPUTS(j) { CHECK_EQ((*i) ^ (*j), r.Call(*i, *j)); }
@@ -410,8 +416,7 @@ WASM_EXEC_TEST(I64Xor) {
WASM_EXEC_TEST(I64Shl) {
REQUIRE(I64Shl);
{
- WasmRunner<uint64_t> r(execution_mode, MachineType::Uint64(),
- MachineType::Uint64());
+ WasmRunner<uint64_t, uint64_t, uint64_t> r(execution_mode);
BUILD(r, WASM_I64_SHL(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_UINT64_INPUTS(i) {
@@ -422,22 +427,22 @@ WASM_EXEC_TEST(I64Shl) {
}
}
{
- WasmRunner<uint64_t> r(execution_mode, MachineType::Int64());
+ WasmRunner<uint64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_SHL(WASM_GET_LOCAL(0), WASM_I64V_1(0)));
FOR_UINT64_INPUTS(i) { CHECK_EQ(*i << 0, r.Call(*i)); }
}
{
- WasmRunner<uint64_t> r(execution_mode, MachineType::Int64());
+ WasmRunner<uint64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_SHL(WASM_GET_LOCAL(0), WASM_I64V_1(32)));
FOR_UINT64_INPUTS(i) { CHECK_EQ(*i << 32, r.Call(*i)); }
}
{
- WasmRunner<uint64_t> r(execution_mode, MachineType::Int64());
+ WasmRunner<uint64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_SHL(WASM_GET_LOCAL(0), WASM_I64V_1(20)));
FOR_UINT64_INPUTS(i) { CHECK_EQ(*i << 20, r.Call(*i)); }
}
{
- WasmRunner<uint64_t> r(execution_mode, MachineType::Int64());
+ WasmRunner<uint64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_SHL(WASM_GET_LOCAL(0), WASM_I64V_1(40)));
FOR_UINT64_INPUTS(i) { CHECK_EQ(*i << 40, r.Call(*i)); }
}
@@ -446,8 +451,7 @@ WASM_EXEC_TEST(I64Shl) {
WASM_EXEC_TEST(I64ShrU) {
REQUIRE(I64ShrU);
{
- WasmRunner<uint64_t> r(execution_mode, MachineType::Uint64(),
- MachineType::Uint64());
+ WasmRunner<uint64_t, uint64_t, uint64_t> r(execution_mode);
BUILD(r, WASM_I64_SHR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_UINT64_INPUTS(i) {
@@ -458,22 +462,22 @@ WASM_EXEC_TEST(I64ShrU) {
}
}
{
- WasmRunner<uint64_t> r(execution_mode, MachineType::Int64());
+ WasmRunner<uint64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_SHR(WASM_GET_LOCAL(0), WASM_I64V_1(0)));
FOR_UINT64_INPUTS(i) { CHECK_EQ(*i >> 0, r.Call(*i)); }
}
{
- WasmRunner<uint64_t> r(execution_mode, MachineType::Int64());
+ WasmRunner<uint64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_SHR(WASM_GET_LOCAL(0), WASM_I64V_1(32)));
FOR_UINT64_INPUTS(i) { CHECK_EQ(*i >> 32, r.Call(*i)); }
}
{
- WasmRunner<uint64_t> r(execution_mode, MachineType::Int64());
+ WasmRunner<uint64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_SHR(WASM_GET_LOCAL(0), WASM_I64V_1(20)));
FOR_UINT64_INPUTS(i) { CHECK_EQ(*i >> 20, r.Call(*i)); }
}
{
- WasmRunner<uint64_t> r(execution_mode, MachineType::Int64());
+ WasmRunner<uint64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_SHR(WASM_GET_LOCAL(0), WASM_I64V_1(40)));
FOR_UINT64_INPUTS(i) { CHECK_EQ(*i >> 40, r.Call(*i)); }
}
@@ -482,8 +486,7 @@ WASM_EXEC_TEST(I64ShrU) {
WASM_EXEC_TEST(I64ShrS) {
REQUIRE(I64ShrS);
{
- WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int64_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_SAR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_INT64_INPUTS(i) {
@@ -494,22 +497,22 @@ WASM_EXEC_TEST(I64ShrS) {
}
}
{
- WasmRunner<int64_t> r(execution_mode, MachineType::Int64());
+ WasmRunner<int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_SAR(WASM_GET_LOCAL(0), WASM_I64V_1(0)));
FOR_INT64_INPUTS(i) { CHECK_EQ(*i >> 0, r.Call(*i)); }
}
{
- WasmRunner<int64_t> r(execution_mode, MachineType::Int64());
+ WasmRunner<int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_SAR(WASM_GET_LOCAL(0), WASM_I64V_1(32)));
FOR_INT64_INPUTS(i) { CHECK_EQ(*i >> 32, r.Call(*i)); }
}
{
- WasmRunner<int64_t> r(execution_mode, MachineType::Int64());
+ WasmRunner<int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_SAR(WASM_GET_LOCAL(0), WASM_I64V_1(20)));
FOR_INT64_INPUTS(i) { CHECK_EQ(*i >> 20, r.Call(*i)); }
}
{
- WasmRunner<int64_t> r(execution_mode, MachineType::Int64());
+ WasmRunner<int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_SAR(WASM_GET_LOCAL(0), WASM_I64V_1(40)));
FOR_INT64_INPUTS(i) { CHECK_EQ(*i >> 40, r.Call(*i)); }
}
@@ -517,8 +520,7 @@ WASM_EXEC_TEST(I64ShrS) {
WASM_EXEC_TEST(I64Eq) {
REQUIRE(I64Eq);
- WasmRunner<int32_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int32_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_EQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_INT64_INPUTS(i) {
FOR_INT64_INPUTS(j) { CHECK_EQ(*i == *j ? 1 : 0, r.Call(*i, *j)); }
@@ -527,8 +529,7 @@ WASM_EXEC_TEST(I64Eq) {
WASM_EXEC_TEST(I64Ne) {
REQUIRE(I64Ne);
- WasmRunner<int32_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int32_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_NE(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_INT64_INPUTS(i) {
FOR_INT64_INPUTS(j) { CHECK_EQ(*i != *j ? 1 : 0, r.Call(*i, *j)); }
@@ -537,8 +538,7 @@ WASM_EXEC_TEST(I64Ne) {
WASM_EXEC_TEST(I64LtS) {
REQUIRE(I64LtS);
- WasmRunner<int32_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int32_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_LTS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_INT64_INPUTS(i) {
FOR_INT64_INPUTS(j) { CHECK_EQ(*i < *j ? 1 : 0, r.Call(*i, *j)); }
@@ -547,8 +547,7 @@ WASM_EXEC_TEST(I64LtS) {
WASM_EXEC_TEST(I64LeS) {
REQUIRE(I64LeS);
- WasmRunner<int32_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int32_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_LES(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_INT64_INPUTS(i) {
FOR_INT64_INPUTS(j) { CHECK_EQ(*i <= *j ? 1 : 0, r.Call(*i, *j)); }
@@ -557,8 +556,7 @@ WASM_EXEC_TEST(I64LeS) {
WASM_EXEC_TEST(I64LtU) {
REQUIRE(I64LtU);
- WasmRunner<int32_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int32_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_LTU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_UINT64_INPUTS(i) {
FOR_UINT64_INPUTS(j) { CHECK_EQ(*i < *j ? 1 : 0, r.Call(*i, *j)); }
@@ -567,8 +565,7 @@ WASM_EXEC_TEST(I64LtU) {
WASM_EXEC_TEST(I64LeU) {
REQUIRE(I64LeU);
- WasmRunner<int32_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int32_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_LEU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_UINT64_INPUTS(i) {
FOR_UINT64_INPUTS(j) { CHECK_EQ(*i <= *j ? 1 : 0, r.Call(*i, *j)); }
@@ -577,8 +574,7 @@ WASM_EXEC_TEST(I64LeU) {
WASM_EXEC_TEST(I64GtS) {
REQUIRE(I64GtS);
- WasmRunner<int32_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int32_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_GTS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_INT64_INPUTS(i) {
FOR_INT64_INPUTS(j) { CHECK_EQ(*i > *j ? 1 : 0, r.Call(*i, *j)); }
@@ -587,8 +583,7 @@ WASM_EXEC_TEST(I64GtS) {
WASM_EXEC_TEST(I64GeS) {
REQUIRE(I64GeS);
- WasmRunner<int32_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int32_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_GES(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_INT64_INPUTS(i) {
FOR_INT64_INPUTS(j) { CHECK_EQ(*i >= *j ? 1 : 0, r.Call(*i, *j)); }
@@ -597,8 +592,7 @@ WASM_EXEC_TEST(I64GeS) {
WASM_EXEC_TEST(I64GtU) {
REQUIRE(I64GtU);
- WasmRunner<int32_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int32_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_GTU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_UINT64_INPUTS(i) {
FOR_UINT64_INPUTS(j) { CHECK_EQ(*i > *j ? 1 : 0, r.Call(*i, *j)); }
@@ -607,8 +601,7 @@ WASM_EXEC_TEST(I64GtU) {
WASM_EXEC_TEST(I64GeU) {
REQUIRE(I64GeU);
- WasmRunner<int32_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int32_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_GEU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_UINT64_INPUTS(i) {
FOR_UINT64_INPUTS(j) { CHECK_EQ(*i >= *j ? 1 : 0, r.Call(*i, *j)); }
@@ -626,14 +619,14 @@ WASM_EXEC_TEST(I32ConvertI64) {
WASM_EXEC_TEST(I64SConvertI32) {
REQUIRE(I64SConvertI32);
- WasmRunner<int64_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int64_t, int32_t> r(execution_mode);
BUILD(r, WASM_I64_SCONVERT_I32(WASM_GET_LOCAL(0)));
FOR_INT32_INPUTS(i) { CHECK_EQ(static_cast<int64_t>(*i), r.Call(*i)); }
}
WASM_EXEC_TEST(I64UConvertI32) {
REQUIRE(I64UConvertI32);
- WasmRunner<int64_t> r(execution_mode, MachineType::Uint32());
+ WasmRunner<int64_t, uint32_t> r(execution_mode);
BUILD(r, WASM_I64_UCONVERT_I32(WASM_GET_LOCAL(0)));
FOR_UINT32_INPUTS(i) { CHECK_EQ(static_cast<int64_t>(*i), r.Call(*i)); }
}
@@ -648,7 +641,7 @@ WASM_EXEC_TEST(I64Popcnt) {
{26, 0x1123456782345678},
{38, 0xffedcba09edcba09}};
- WasmRunner<int64_t> r(execution_mode, MachineType::Uint64());
+ WasmRunner<int64_t, uint64_t> r(execution_mode);
BUILD(r, WASM_I64_POPCNT(WASM_GET_LOCAL(0)));
for (size_t i = 0; i < arraysize(values); i++) {
CHECK_EQ(values[i].expected, r.Call(values[i].input));
@@ -657,7 +650,7 @@ WASM_EXEC_TEST(I64Popcnt) {
WASM_EXEC_TEST(F32SConvertI64) {
REQUIRE(F32SConvertI64);
- WasmRunner<float> r(execution_mode, MachineType::Int64());
+ WasmRunner<float, int64_t> r(execution_mode);
BUILD(r, WASM_F32_SCONVERT_I64(WASM_GET_LOCAL(0)));
FOR_INT64_INPUTS(i) { CHECK_FLOAT_EQ(static_cast<float>(*i), r.Call(*i)); }
}
@@ -743,7 +736,7 @@ WASM_EXEC_TEST(F32UConvertI64) {
{0x8000008000000001, 0x5f000001},
{0x8000000000000400, 0x5f000000},
{0x8000000000000401, 0x5f000000}};
- WasmRunner<float> r(execution_mode, MachineType::Uint64());
+ WasmRunner<float, uint64_t> r(execution_mode);
BUILD(r, WASM_F32_UCONVERT_I64(WASM_GET_LOCAL(0)));
for (size_t i = 0; i < arraysize(values); i++) {
CHECK_EQ(bit_cast<float>(values[i].expected), r.Call(values[i].input));
@@ -752,7 +745,7 @@ WASM_EXEC_TEST(F32UConvertI64) {
WASM_EXEC_TEST(F64SConvertI64) {
REQUIRE(F64SConvertI64);
- WasmRunner<double> r(execution_mode, MachineType::Int64());
+ WasmRunner<double, int64_t> r(execution_mode);
BUILD(r, WASM_F64_SCONVERT_I64(WASM_GET_LOCAL(0)));
FOR_INT64_INPUTS(i) { CHECK_DOUBLE_EQ(static_cast<double>(*i), r.Call(*i)); }
}
@@ -837,15 +830,15 @@ WASM_EXEC_TEST(F64UConvertI64) {
{0x8000008000000001, 0x43e0000010000000},
{0x8000000000000400, 0x43e0000000000000},
{0x8000000000000401, 0x43e0000000000001}};
- WasmRunner<double> r(execution_mode, MachineType::Uint64());
+ WasmRunner<double, uint64_t> r(execution_mode);
BUILD(r, WASM_F64_UCONVERT_I64(WASM_GET_LOCAL(0)));
for (size_t i = 0; i < arraysize(values); i++) {
CHECK_EQ(bit_cast<double>(values[i].expected), r.Call(values[i].input));
}
}
-WASM_EXEC_TEST(I64SConvertF32a) {
- WasmRunner<int64_t> r(execution_mode, MachineType::Float32());
+WASM_EXEC_TEST_WITH_TRAP(I64SConvertF32a) {
+ WasmRunner<int64_t, float> r(execution_mode);
BUILD(r, WASM_I64_SCONVERT_F32(WASM_GET_LOCAL(0)));
FOR_FLOAT32_INPUTS(i) {
@@ -858,8 +851,8 @@ WASM_EXEC_TEST(I64SConvertF32a) {
}
}
-WASM_EXEC_TEST(I64SConvertF64a) {
- WasmRunner<int64_t> r(execution_mode, MachineType::Float64());
+WASM_EXEC_TEST_WITH_TRAP(I64SConvertF64a) {
+ WasmRunner<int64_t, double> r(execution_mode);
BUILD(r, WASM_I64_SCONVERT_F64(WASM_GET_LOCAL(0)));
FOR_FLOAT64_INPUTS(i) {
@@ -872,8 +865,8 @@ WASM_EXEC_TEST(I64SConvertF64a) {
}
}
-WASM_EXEC_TEST(I64UConvertF32a) {
- WasmRunner<uint64_t> r(execution_mode, MachineType::Float32());
+WASM_EXEC_TEST_WITH_TRAP(I64UConvertF32a) {
+ WasmRunner<uint64_t, float> r(execution_mode);
BUILD(r, WASM_I64_UCONVERT_F32(WASM_GET_LOCAL(0)));
FOR_FLOAT32_INPUTS(i) {
@@ -886,8 +879,8 @@ WASM_EXEC_TEST(I64UConvertF32a) {
}
}
-WASM_EXEC_TEST(I64UConvertF64a) {
- WasmRunner<uint64_t> r(execution_mode, MachineType::Float64());
+WASM_EXEC_TEST_WITH_TRAP(I64UConvertF64a) {
+ WasmRunner<uint64_t, double> r(execution_mode);
BUILD(r, WASM_I64_UCONVERT_F64(WASM_GET_LOCAL(0)));
FOR_FLOAT64_INPUTS(i) {
@@ -901,28 +894,23 @@ WASM_EXEC_TEST(I64UConvertF64a) {
}
WASM_EXEC_TEST(CallI64Parameter) {
- // Build the target function.
- LocalType param_types[20];
- for (int i = 0; i < 20; i++) param_types[i] = kAstI64;
- param_types[3] = kAstI32;
- param_types[4] = kAstI32;
+ ValueType param_types[20];
+ for (int i = 0; i < 20; i++) param_types[i] = kWasmI64;
+ param_types[3] = kWasmI32;
+ param_types[4] = kWasmI32;
FunctionSig sig(1, 19, param_types);
for (int i = 0; i < 19; i++) {
- TestingModule module(execution_mode);
- WasmFunctionCompiler t(&sig, &module);
- if (i == 2 || i == 3) {
- continue;
- } else {
- BUILD(t, WASM_GET_LOCAL(i));
- }
- uint32_t index = t.CompileAndAdd();
+ if (i == 2 || i == 3) continue;
+ WasmRunner<int32_t> r(execution_mode);
+ // Build the target function.
+ WasmFunctionCompiler& t = r.NewFunction(&sig);
+ BUILD(t, WASM_GET_LOCAL(i));
// Build the calling function.
- WasmRunner<int32_t> r(&module);
BUILD(
r,
WASM_I32_CONVERT_I64(WASM_CALL_FUNCTION(
- index, WASM_I64V_9(0xbcd12340000000b),
+ t.function_index(), WASM_I64V_9(0xbcd12340000000b),
WASM_I64V_9(0xbcd12340000000c), WASM_I32V_1(0xd),
WASM_I32_CONVERT_I64(WASM_I64V_9(0xbcd12340000000e)),
WASM_I64V_9(0xbcd12340000000f), WASM_I64V_10(0xbcd1234000000010),
@@ -947,8 +935,7 @@ void TestI64Binop(WasmExecutionMode execution_mode, WasmOpcode opcode,
CHECK_EQ(expected, r.Call());
}
{
- WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int64_t, int64_t, int64_t> r(execution_mode);
// return a op b
BUILD(r, WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
CHECK_EQ(expected, r.Call(a, b));
@@ -964,8 +951,7 @@ void TestI64Cmp(WasmExecutionMode execution_mode, WasmOpcode opcode,
CHECK_EQ(expected, r.Call());
}
{
- WasmRunner<int32_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int32_t, int64_t, int64_t> r(execution_mode);
// return a op b
BUILD(r, WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
CHECK_EQ(expected, r.Call(a, b));
@@ -1068,7 +1054,7 @@ WASM_EXEC_TEST(I64Clz) {
{62, 0x0000000000000002}, {63, 0x0000000000000001},
{64, 0x0000000000000000}};
- WasmRunner<int64_t> r(execution_mode, MachineType::Uint64());
+ WasmRunner<int64_t, uint64_t> r(execution_mode);
BUILD(r, WASM_I64_CLZ(WASM_GET_LOCAL(0)));
for (size_t i = 0; i < arraysize(values); i++) {
CHECK_EQ(values[i].expected, r.Call(values[i].input));
@@ -1114,7 +1100,7 @@ WASM_EXEC_TEST(I64Ctz) {
{2, 0x000000009afdbc84}, {1, 0x000000009afdbc82},
{0, 0x000000009afdbc81}};
- WasmRunner<int64_t> r(execution_mode, MachineType::Uint64());
+ WasmRunner<int64_t, uint64_t> r(execution_mode);
BUILD(r, WASM_I64_CTZ(WASM_GET_LOCAL(0)));
for (size_t i = 0; i < arraysize(values); i++) {
CHECK_EQ(values[i].expected, r.Call(values[i].input));
@@ -1132,7 +1118,7 @@ WASM_EXEC_TEST(I64Popcnt2) {
{26, 0x1123456782345678},
{38, 0xffedcba09edcba09}};
- WasmRunner<int64_t> r(execution_mode, MachineType::Uint64());
+ WasmRunner<int64_t, uint64_t> r(execution_mode);
BUILD(r, WASM_I64_POPCNT(WASM_GET_LOCAL(0)));
for (size_t i = 0; i < arraysize(values); i++) {
CHECK_EQ(values[i].expected, r.Call(values[i].input));
@@ -1150,21 +1136,19 @@ WASM_EXEC_TEST(I64WasmRunner) {
}
}
{
- WasmRunner<int64_t> r(execution_mode, MachineType::Int64());
+ WasmRunner<int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_GET_LOCAL(0));
FOR_INT64_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
}
{
- WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int64_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_XOR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_INT64_INPUTS(i) {
FOR_INT64_INPUTS(j) { CHECK_EQ(*i ^ *j, r.Call(*i, *j)); }
}
}
{
- WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64(), MachineType::Int64());
+ WasmRunner<int64_t, int64_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_XOR(WASM_GET_LOCAL(0),
WASM_I64_XOR(WASM_GET_LOCAL(1), WASM_GET_LOCAL(2))));
FOR_INT64_INPUTS(i) {
@@ -1176,9 +1160,7 @@ WASM_EXEC_TEST(I64WasmRunner) {
}
}
{
- WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64(), MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int64_t, int64_t, int64_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_XOR(WASM_GET_LOCAL(0),
WASM_I64_XOR(WASM_GET_LOCAL(1),
WASM_I64_XOR(WASM_GET_LOCAL(2),
@@ -1196,16 +1178,15 @@ WASM_EXEC_TEST(I64WasmRunner) {
WASM_EXEC_TEST(Call_Int64Sub) {
REQUIRE(I64Sub);
+ WasmRunner<int64_t, int64_t, int64_t> r(execution_mode);
// Build the target function.
TestSignatures sigs;
- TestingModule module(execution_mode);
- WasmFunctionCompiler t(sigs.l_ll(), &module);
+ WasmFunctionCompiler& t = r.NewFunction(sigs.l_ll());
BUILD(t, WASM_I64_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
- uint32_t index = t.CompileAndAdd();
// Build the caller function.
- WasmRunner<int64_t> r(&module, MachineType::Int64(), MachineType::Int64());
- BUILD(r, WASM_CALL_FUNCTION(index, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
+ BUILD(r, WASM_CALL_FUNCTION(t.function_index(), WASM_GET_LOCAL(0),
+ WASM_GET_LOCAL(1)));
FOR_INT32_INPUTS(i) {
FOR_INT32_INPUTS(j) {
@@ -1228,20 +1209,19 @@ WASM_EXEC_TEST(LoadStoreI64_sx) {
kExprI64LoadMem};
for (size_t m = 0; m < arraysize(loads); m++) {
- TestingModule module(execution_mode);
- byte* memory = module.AddMemoryElems<byte>(16);
- WasmRunner<int64_t> r(&module);
+ WasmRunner<int64_t> r(execution_mode);
+ byte* memory = r.module().AddMemoryElems<byte>(16);
byte code[] = {
- kExprI8Const, 8, // --
- kExprI8Const, 0, // --
+ kExprI32Const, 8, // --
+ kExprI32Const, 0, // --
loads[m], // --
ZERO_ALIGNMENT, // --
ZERO_OFFSET, // --
kExprI64StoreMem, // --
ZERO_ALIGNMENT, // --
ZERO_OFFSET, // --
- kExprI8Const, 0, // --
+ kExprI32Const, 0, // --
loads[m], // --
ZERO_ALIGNMENT, // --
ZERO_OFFSET, // --
@@ -1252,7 +1232,7 @@ WASM_EXEC_TEST(LoadStoreI64_sx) {
// Try a bunch of different negative values.
for (int i = -1; i >= -128; i -= 11) {
int size = 1 << m;
- module.BlankMemory();
+ r.module().BlankMemory();
memory[size - 1] = static_cast<byte>(i); // set the high order byte.
int64_t expected = static_cast<int64_t>(i) << ((size - 1) * 8);
@@ -1266,9 +1246,9 @@ WASM_EXEC_TEST(LoadStoreI64_sx) {
}
}
-WASM_EXEC_TEST(I64SConvertF32b) {
+WASM_EXEC_TEST_WITH_TRAP(I64SConvertF32b) {
REQUIRE(I64SConvertF32);
- WasmRunner<int64_t> r(execution_mode, MachineType::Float32());
+ WasmRunner<int64_t, float> r(execution_mode);
BUILD(r, WASM_I64_SCONVERT_F32(WASM_GET_LOCAL(0)));
FOR_FLOAT32_INPUTS(i) {
@@ -1281,9 +1261,9 @@ WASM_EXEC_TEST(I64SConvertF32b) {
}
}
-WASM_EXEC_TEST(I64SConvertF64b) {
+WASM_EXEC_TEST_WITH_TRAP(I64SConvertF64b) {
REQUIRE(I64SConvertF64);
- WasmRunner<int64_t> r(execution_mode, MachineType::Float64());
+ WasmRunner<int64_t, double> r(execution_mode);
BUILD(r, WASM_I64_SCONVERT_F64(WASM_GET_LOCAL(0)));
FOR_FLOAT64_INPUTS(i) {
@@ -1296,9 +1276,9 @@ WASM_EXEC_TEST(I64SConvertF64b) {
}
}
-WASM_EXEC_TEST(I64UConvertF32b) {
+WASM_EXEC_TEST_WITH_TRAP(I64UConvertF32b) {
REQUIRE(I64UConvertF32);
- WasmRunner<uint64_t> r(execution_mode, MachineType::Float32());
+ WasmRunner<uint64_t, float> r(execution_mode);
BUILD(r, WASM_I64_UCONVERT_F32(WASM_GET_LOCAL(0)));
FOR_FLOAT32_INPUTS(i) {
@@ -1310,9 +1290,9 @@ WASM_EXEC_TEST(I64UConvertF32b) {
}
}
-WASM_EXEC_TEST(I64UConvertF64b) {
+WASM_EXEC_TEST_WITH_TRAP(I64UConvertF64b) {
REQUIRE(I64UConvertF64);
- WasmRunner<uint64_t> r(execution_mode, MachineType::Float64());
+ WasmRunner<uint64_t, double> r(execution_mode);
BUILD(r, WASM_I64_UCONVERT_F64(WASM_GET_LOCAL(0)));
FOR_FLOAT64_INPUTS(i) {
@@ -1326,25 +1306,33 @@ WASM_EXEC_TEST(I64UConvertF64b) {
WASM_EXEC_TEST(I64ReinterpretF64) {
REQUIRE(I64ReinterpretF64);
- TestingModule module(execution_mode);
- int64_t* memory = module.AddMemoryElems<int64_t>(8);
- WasmRunner<int64_t> r(&module);
+ WasmRunner<int64_t> r(execution_mode);
+ int64_t* memory = r.module().AddMemoryElems<int64_t>(8);
BUILD(r, WASM_I64_REINTERPRET_F64(
WASM_LOAD_MEM(MachineType::Float64(), WASM_ZERO)));
FOR_INT32_INPUTS(i) {
int64_t expected = static_cast<int64_t>(*i) * 0x300010001;
- module.WriteMemory(&memory[0], expected);
+ r.module().WriteMemory(&memory[0], expected);
CHECK_EQ(expected, r.Call());
}
}
+WASM_EXEC_TEST(SignallingNanSurvivesI64ReinterpretF64) {
+ REQUIRE(I64ReinterpretF64);
+ WasmRunner<int64_t> r(execution_mode);
+ BUILD(r, WASM_I64_REINTERPRET_F64(WASM_SEQ(kExprF64Const, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xf4, 0x7f)));
+
+ // This is a signalling nan.
+ CHECK_EQ(0x7ff4000000000000, r.Call());
+}
+
WASM_EXEC_TEST(F64ReinterpretI64) {
REQUIRE(F64ReinterpretI64);
- TestingModule module(execution_mode);
- int64_t* memory = module.AddMemoryElems<int64_t>(8);
- WasmRunner<int64_t> r(&module, MachineType::Int64());
+ WasmRunner<int64_t, int64_t> r(execution_mode);
+ int64_t* memory = r.module().AddMemoryElems<int64_t>(8);
BUILD(r, WASM_STORE_MEM(MachineType::Float64(), WASM_ZERO,
WASM_F64_REINTERPRET_I64(WASM_GET_LOCAL(0))),
@@ -1353,47 +1341,45 @@ WASM_EXEC_TEST(F64ReinterpretI64) {
FOR_INT32_INPUTS(i) {
int64_t expected = static_cast<int64_t>(*i) * 0x300010001;
CHECK_EQ(expected, r.Call(expected));
- CHECK_EQ(expected, module.ReadMemory<int64_t>(&memory[0]));
+ CHECK_EQ(expected, r.module().ReadMemory<int64_t>(&memory[0]));
}
}
WASM_EXEC_TEST(LoadMemI64) {
REQUIRE(I64LoadStore);
- TestingModule module(execution_mode);
- int64_t* memory = module.AddMemoryElems<int64_t>(8);
- module.RandomizeMemory(1111);
- WasmRunner<int64_t> r(&module);
+ WasmRunner<int64_t> r(execution_mode);
+ int64_t* memory = r.module().AddMemoryElems<int64_t>(8);
+ r.module().RandomizeMemory(1111);
- BUILD(r, WASM_LOAD_MEM(MachineType::Int64(), WASM_I8(0)));
+ BUILD(r, WASM_LOAD_MEM(MachineType::Int64(), WASM_ZERO));
- module.WriteMemory<int64_t>(&memory[0], 0x1abbccdd00112233LL);
+ r.module().WriteMemory<int64_t>(&memory[0], 0x1abbccdd00112233LL);
CHECK_EQ(0x1abbccdd00112233LL, r.Call());
- module.WriteMemory<int64_t>(&memory[0], 0x33aabbccdd001122LL);
+ r.module().WriteMemory<int64_t>(&memory[0], 0x33aabbccdd001122LL);
CHECK_EQ(0x33aabbccdd001122LL, r.Call());
- module.WriteMemory<int64_t>(&memory[0], 77777777);
+ r.module().WriteMemory<int64_t>(&memory[0], 77777777);
CHECK_EQ(77777777, r.Call());
}
WASM_EXEC_TEST(LoadMemI64_alignment) {
REQUIRE(I64LoadStore);
- TestingModule module(execution_mode);
- int64_t* memory = module.AddMemoryElems<int64_t>(8);
for (byte alignment = 0; alignment <= 3; alignment++) {
- module.RandomizeMemory(1111);
- WasmRunner<int64_t> r(&module);
+ WasmRunner<int64_t> r(execution_mode);
+ int64_t* memory = r.module().AddMemoryElems<int64_t>(8);
+ r.module().RandomizeMemory(1111);
BUILD(r,
- WASM_LOAD_MEM_ALIGNMENT(MachineType::Int64(), WASM_I8(0), alignment));
+ WASM_LOAD_MEM_ALIGNMENT(MachineType::Int64(), WASM_ZERO, alignment));
- module.WriteMemory<int64_t>(&memory[0], 0x1abbccdd00112233LL);
+ r.module().WriteMemory<int64_t>(&memory[0], 0x1abbccdd00112233LL);
CHECK_EQ(0x1abbccdd00112233LL, r.Call());
- module.WriteMemory<int64_t>(&memory[0], 0x33aabbccdd001122LL);
+ r.module().WriteMemory<int64_t>(&memory[0], 0x33aabbccdd001122LL);
CHECK_EQ(0x33aabbccdd001122LL, r.Call());
- module.WriteMemory<int64_t>(&memory[0], 77777777);
+ r.module().WriteMemory<int64_t>(&memory[0], 77777777);
CHECK_EQ(77777777, r.Call());
}
}
@@ -1404,29 +1390,27 @@ WASM_EXEC_TEST(MemI64_Sum) {
REQUIRE(I64Sub);
REQUIRE(I64Phi);
const int kNumElems = 20;
- TestingModule module(execution_mode);
- uint64_t* memory = module.AddMemoryElems<uint64_t>(kNumElems);
- WasmRunner<uint64_t> r(&module, MachineType::Int32());
- const byte kSum = r.AllocateLocal(kAstI64);
-
- BUILD(
- r,
- WASM_WHILE(
- WASM_GET_LOCAL(0),
- WASM_BLOCK(
- WASM_SET_LOCAL(kSum,
- WASM_I64_ADD(WASM_GET_LOCAL(kSum),
+ WasmRunner<uint64_t, int32_t> r(execution_mode);
+ uint64_t* memory = r.module().AddMemoryElems<uint64_t>(kNumElems);
+ const byte kSum = r.AllocateLocal(kWasmI64);
+
+ BUILD(r, WASM_WHILE(
+ WASM_GET_LOCAL(0),
+ WASM_BLOCK(
+ WASM_SET_LOCAL(
+ kSum, WASM_I64_ADD(WASM_GET_LOCAL(kSum),
WASM_LOAD_MEM(MachineType::Int64(),
WASM_GET_LOCAL(0)))),
- WASM_SET_LOCAL(0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(8))))),
- WASM_GET_LOCAL(1));
+ WASM_SET_LOCAL(
+ 0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I32V_1(8))))),
+ WASM_GET_LOCAL(1));
// Run 4 trials.
for (int i = 0; i < 3; i++) {
- module.RandomizeMemory(i * 33);
+ r.module().RandomizeMemory(i * 33);
uint64_t expected = 0;
for (size_t j = kNumElems - 1; j > 0; j--) {
- expected += module.ReadMemory(&memory[j]);
+ expected += r.module().ReadMemory(&memory[j]);
}
uint64_t result = r.Call(8 * (kNumElems - 1));
CHECK_EQ(expected, result);
@@ -1434,20 +1418,19 @@ WASM_EXEC_TEST(MemI64_Sum) {
}
WASM_EXEC_TEST(StoreMemI64_alignment) {
- TestingModule module(execution_mode);
- int64_t* memory = module.AddMemoryElems<int64_t>(4);
const int64_t kWritten = 0x12345678abcd0011ll;
for (byte i = 0; i <= 3; i++) {
- WasmRunner<int64_t> r(&module, MachineType::Int64());
+ WasmRunner<int64_t, int64_t> r(execution_mode);
+ int64_t* memory = r.module().AddMemoryElems<int64_t>(4);
BUILD(r, WASM_STORE_MEM_ALIGNMENT(MachineType::Int64(), WASM_ZERO, i,
WASM_GET_LOCAL(0)),
WASM_GET_LOCAL(0));
- module.RandomizeMemory(1111);
- module.WriteMemory<int64_t>(&memory[0], 0);
+ r.module().RandomizeMemory(1111);
+ r.module().WriteMemory<int64_t>(&memory[0], 0);
CHECK_EQ(kWritten, r.Call(kWritten));
- CHECK_EQ(kWritten, module.ReadMemory(&memory[0]));
+ CHECK_EQ(kWritten, r.module().ReadMemory(&memory[0]));
}
}
@@ -1456,16 +1439,15 @@ WASM_EXEC_TEST(I64Global) {
REQUIRE(I64SConvertI32);
REQUIRE(I64And);
REQUIRE(DepthFirst);
- TestingModule module(execution_mode);
- int64_t* global = module.AddGlobal<int64_t>(kAstI64);
- WasmRunner<int32_t> r(&module, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ int64_t* global = r.module().AddGlobal<int64_t>();
// global = global + p0
BUILD(r, WASM_SET_GLOBAL(
0, WASM_I64_AND(WASM_GET_GLOBAL(0),
WASM_I64_SCONVERT_I32(WASM_GET_LOCAL(0)))),
WASM_ZERO);
- module.WriteMemory<int64_t>(global, 0xFFFFFFFFFFFFFFFFLL);
+ r.module().WriteMemory<int64_t>(global, 0xFFFFFFFFFFFFFFFFLL);
for (int i = 9; i < 444444; i += 111111) {
int64_t expected = *global & i;
r.Call(i);
@@ -1476,7 +1458,7 @@ WASM_EXEC_TEST(I64Global) {
WASM_EXEC_TEST(I64Eqz) {
REQUIRE(I64Eq);
- WasmRunner<int32_t> r(execution_mode, MachineType::Int64());
+ WasmRunner<int32_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_EQZ(WASM_GET_LOCAL(0)));
FOR_INT64_INPUTS(i) {
@@ -1487,8 +1469,7 @@ WASM_EXEC_TEST(I64Eqz) {
WASM_EXEC_TEST(I64Ror) {
REQUIRE(I64Ror);
- WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int64_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_ROR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_UINT64_INPUTS(i) {
@@ -1501,8 +1482,7 @@ WASM_EXEC_TEST(I64Ror) {
WASM_EXEC_TEST(I64Rol) {
REQUIRE(I64Rol);
- WasmRunner<int64_t> r(execution_mode, MachineType::Int64(),
- MachineType::Int64());
+ WasmRunner<int64_t, int64_t, int64_t> r(execution_mode);
BUILD(r, WASM_I64_ROL(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_UINT64_INPUTS(i) {
@@ -1513,10 +1493,7 @@ WASM_EXEC_TEST(I64Rol) {
}
}
-WASM_EXEC_TEST(StoreMem_offset_oob_i64) {
- TestingModule module(execution_mode);
- byte* memory = module.AddMemoryElems<byte>(32);
-
+WASM_EXEC_TEST_WITH_TRAP(StoreMem_offset_oob_i64) {
static const MachineType machineTypes[] = {
MachineType::Int8(), MachineType::Uint8(), MachineType::Int16(),
MachineType::Uint16(), MachineType::Int32(), MachineType::Uint32(),
@@ -1524,8 +1501,9 @@ WASM_EXEC_TEST(StoreMem_offset_oob_i64) {
MachineType::Float64()};
for (size_t m = 0; m < arraysize(machineTypes); m++) {
- module.RandomizeMemory(1119 + static_cast<int>(m));
- WasmRunner<int32_t> r(&module, MachineType::Uint32());
+ WasmRunner<int32_t, uint32_t> r(execution_mode);
+ byte* memory = r.module().AddMemoryElems<byte>(32);
+ r.module().RandomizeMemory(1119 + static_cast<int>(m));
BUILD(r, WASM_STORE_MEM_OFFSET(machineTypes[m], 8, WASM_GET_LOCAL(0),
WASM_LOAD_MEM(machineTypes[m], WASM_ZERO)),
@@ -1548,36 +1526,32 @@ WASM_EXEC_TEST(StoreMem_offset_oob_i64) {
for (size_t i = 0; i < sizeof(__buf); i++) vec.push_back(__buf[i]); \
} while (false)
-static void CompileCallIndirectMany(LocalType param) {
+static void CompileCallIndirectMany(ValueType param) {
// Make sure we don't run out of registers when compiling indirect calls
// with many many parameters.
TestSignatures sigs;
for (byte num_params = 0; num_params < 40; num_params++) {
- v8::internal::AccountingAllocator allocator;
- Zone zone(&allocator, ZONE_NAME);
- HandleScope scope(CcTest::InitIsolateOnce());
- TestingModule module(kExecuteCompiled);
- FunctionSig* sig = sigs.many(&zone, kAstStmt, param, num_params);
+ WasmRunner<void> r(kExecuteCompiled);
+ FunctionSig* sig = sigs.many(r.zone(), kWasmStmt, param, num_params);
- module.AddSignature(sig);
- module.AddSignature(sig);
- module.AddIndirectFunctionTable(nullptr, 0);
+ r.module().AddSignature(sig);
+ r.module().AddSignature(sig);
+ r.module().AddIndirectFunctionTable(nullptr, 0);
- WasmFunctionCompiler t(sig, &module);
+ WasmFunctionCompiler& t = r.NewFunction(sig);
std::vector<byte> code;
for (byte p = 0; p < num_params; p++) {
ADD_CODE(code, kExprGetLocal, p);
}
- ADD_CODE(code, kExprI8Const, 0);
+ ADD_CODE(code, kExprI32Const, 0);
ADD_CODE(code, kExprCallIndirect, 1, TABLE_ZERO);
t.Build(&code[0], &code[0] + code.size());
- t.Compile();
}
}
-TEST(Compile_Wasm_CallIndirect_Many_i64) { CompileCallIndirectMany(kAstI64); }
+TEST(Compile_Wasm_CallIndirect_Many_i64) { CompileCallIndirectMany(kWasmI64); }
static void Run_WasmMixedCall_N(WasmExecutionMode execution_mode, int start) {
const int kExpected = 6333;
@@ -1595,28 +1569,25 @@ static void Run_WasmMixedCall_N(WasmExecutionMode execution_mode, int start) {
for (int which = 0; which < num_params; which++) {
v8::internal::AccountingAllocator allocator;
Zone zone(&allocator, ZONE_NAME);
- TestingModule module(execution_mode);
- module.AddMemory(1024);
+ WasmRunner<int32_t> r(execution_mode);
+ r.module().AddMemory(1024);
MachineType* memtypes = &mixed[start];
MachineType result = memtypes[which];
// =========================================================================
// Build the selector function.
// =========================================================================
- uint32_t index;
FunctionSig::Builder b(&zone, 1, num_params);
- b.AddReturn(WasmOpcodes::LocalTypeFor(result));
+ b.AddReturn(WasmOpcodes::ValueTypeFor(result));
for (int i = 0; i < num_params; i++) {
- b.AddParam(WasmOpcodes::LocalTypeFor(memtypes[i]));
+ b.AddParam(WasmOpcodes::ValueTypeFor(memtypes[i]));
}
- WasmFunctionCompiler t(b.Build(), &module);
+ WasmFunctionCompiler& t = r.NewFunction(b.Build());
BUILD(t, WASM_GET_LOCAL(which));
- index = t.CompileAndAdd();
// =========================================================================
// Build the calling function.
// =========================================================================
- WasmRunner<int32_t> r(&module);
std::vector<byte> code;
// Load the offset for the store.
@@ -1625,11 +1596,11 @@ static void Run_WasmMixedCall_N(WasmExecutionMode execution_mode, int start) {
// Load the arguments.
for (int i = 0; i < num_params; i++) {
int offset = (i + 1) * kElemSize;
- ADD_CODE(code, WASM_LOAD_MEM(memtypes[i], WASM_I8(offset)));
+ ADD_CODE(code, WASM_LOAD_MEM(memtypes[i], WASM_I32V_2(offset)));
}
// Call the selector function.
- ADD_CODE(code, kExprCallFunction, static_cast<byte>(index));
+ ADD_CODE(code, WASM_CALL_FUNCTION0(t.function_index()));
// Store the result in memory.
ADD_CODE(code,
@@ -1643,14 +1614,14 @@ static void Run_WasmMixedCall_N(WasmExecutionMode execution_mode, int start) {
// Run the code.
for (int t = 0; t < 10; t++) {
- module.RandomizeMemory();
+ r.module().RandomizeMemory();
CHECK_EQ(kExpected, r.Call());
int size = WasmOpcodes::MemSize(result);
for (int i = 0; i < size; i++) {
int base = (which + 1) * kElemSize;
- byte expected = module.raw_mem_at<byte>(base + i);
- byte result = module.raw_mem_at<byte>(i);
+ byte expected = r.module().raw_mem_at<byte>(base + i);
+ byte result = r.module().raw_mem_at<byte>(i);
CHECK_EQ(expected, result);
}
}
@@ -1661,3 +1632,19 @@ WASM_EXEC_TEST(MixedCall_i64_0) { Run_WasmMixedCall_N(execution_mode, 0); }
WASM_EXEC_TEST(MixedCall_i64_1) { Run_WasmMixedCall_N(execution_mode, 1); }
WASM_EXEC_TEST(MixedCall_i64_2) { Run_WasmMixedCall_N(execution_mode, 2); }
WASM_EXEC_TEST(MixedCall_i64_3) { Run_WasmMixedCall_N(execution_mode, 3); }
+
+WASM_EXEC_TEST(Regress5874) {
+ REQUIRE(I32ConvertI64);
+ REQUIRE(I64LoadStore);
+ REQUIRE(I64Const);
+ WasmRunner<int32_t> r(execution_mode);
+ r.module().AddMemoryElems<int64_t>(8);
+
+ BUILD(r, kExprI64Const, 0x00, // --
+ kExprI32ConvertI64, // --
+ kExprI64Const, 0x00, // --
+ kExprI64StoreMem, 0x03, 0x00, // --
+ kExprI32Const, 0x00); // --
+
+ r.Call();
+}
diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-asmjs.cc b/deps/v8/test/cctest/wasm/test-run-wasm-asmjs.cc
index bd80e28f9f..38430f292c 100644
--- a/deps/v8/test/cctest/wasm/test-run-wasm-asmjs.cc
+++ b/deps/v8/test/cctest/wasm/test-run-wasm-asmjs.cc
@@ -38,9 +38,8 @@ uint32_t GetMatchingRelocInfoCount(Handle<Code> code, RelocInfo::Mode rmode) {
}
WASM_EXEC_TEST(Int32AsmjsDivS) {
- TestingModule module(execution_mode);
- module.origin = kAsmJsOrigin;
- WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32());
+ WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
+ r.module().ChangeOriginToAsmjs();
BUILD(r, WASM_BINOP(kExprI32AsmjsDivS, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
const int32_t kMin = std::numeric_limits<int32_t>::min();
CHECK_EQ(0, r.Call(0, 100));
@@ -51,9 +50,8 @@ WASM_EXEC_TEST(Int32AsmjsDivS) {
}
WASM_EXEC_TEST(Int32AsmjsRemS) {
- TestingModule module(execution_mode);
- module.origin = kAsmJsOrigin;
- WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32());
+ WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
+ r.module().ChangeOriginToAsmjs();
BUILD(r, WASM_BINOP(kExprI32AsmjsRemS, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
const int32_t kMin = std::numeric_limits<int32_t>::min();
CHECK_EQ(33, r.Call(133, 100));
@@ -64,9 +62,8 @@ WASM_EXEC_TEST(Int32AsmjsRemS) {
}
WASM_EXEC_TEST(Int32AsmjsDivU) {
- TestingModule module(execution_mode);
- module.origin = kAsmJsOrigin;
- WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32());
+ WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
+ r.module().ChangeOriginToAsmjs();
BUILD(r, WASM_BINOP(kExprI32AsmjsDivU, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
const int32_t kMin = std::numeric_limits<int32_t>::min();
CHECK_EQ(0, r.Call(0, 100));
@@ -77,9 +74,8 @@ WASM_EXEC_TEST(Int32AsmjsDivU) {
}
WASM_EXEC_TEST(Int32AsmjsRemU) {
- TestingModule module(execution_mode);
- module.origin = kAsmJsOrigin;
- WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32());
+ WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
+ r.module().ChangeOriginToAsmjs();
BUILD(r, WASM_BINOP(kExprI32AsmjsRemU, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
const int32_t kMin = std::numeric_limits<int32_t>::min();
CHECK_EQ(17, r.Call(217, 100));
@@ -90,9 +86,8 @@ WASM_EXEC_TEST(Int32AsmjsRemU) {
}
WASM_EXEC_TEST(I32AsmjsSConvertF32) {
- TestingModule module(execution_mode);
- module.origin = kAsmJsOrigin;
- WasmRunner<int32_t> r(&module, MachineType::Float32());
+ WasmRunner<int32_t, float> r(execution_mode);
+ r.module().ChangeOriginToAsmjs();
BUILD(r, WASM_UNOP(kExprI32AsmjsSConvertF32, WASM_GET_LOCAL(0)));
FOR_FLOAT32_INPUTS(i) {
@@ -102,9 +97,8 @@ WASM_EXEC_TEST(I32AsmjsSConvertF32) {
}
WASM_EXEC_TEST(I32AsmjsSConvertF64) {
- TestingModule module(execution_mode);
- module.origin = kAsmJsOrigin;
- WasmRunner<int32_t> r(&module, MachineType::Float64());
+ WasmRunner<int32_t, double> r(execution_mode);
+ r.module().ChangeOriginToAsmjs();
BUILD(r, WASM_UNOP(kExprI32AsmjsSConvertF64, WASM_GET_LOCAL(0)));
FOR_FLOAT64_INPUTS(i) {
@@ -114,9 +108,8 @@ WASM_EXEC_TEST(I32AsmjsSConvertF64) {
}
WASM_EXEC_TEST(I32AsmjsUConvertF32) {
- TestingModule module(execution_mode);
- module.origin = kAsmJsOrigin;
- WasmRunner<uint32_t> r(&module, MachineType::Float32());
+ WasmRunner<uint32_t, float> r(execution_mode);
+ r.module().ChangeOriginToAsmjs();
BUILD(r, WASM_UNOP(kExprI32AsmjsUConvertF32, WASM_GET_LOCAL(0)));
FOR_FLOAT32_INPUTS(i) {
@@ -126,9 +119,8 @@ WASM_EXEC_TEST(I32AsmjsUConvertF32) {
}
WASM_EXEC_TEST(I32AsmjsUConvertF64) {
- TestingModule module(execution_mode);
- module.origin = kAsmJsOrigin;
- WasmRunner<uint32_t> r(&module, MachineType::Float64());
+ WasmRunner<uint32_t, double> r(execution_mode);
+ r.module().ChangeOriginToAsmjs();
BUILD(r, WASM_UNOP(kExprI32AsmjsUConvertF64, WASM_GET_LOCAL(0)));
FOR_FLOAT64_INPUTS(i) {
@@ -138,11 +130,10 @@ WASM_EXEC_TEST(I32AsmjsUConvertF64) {
}
WASM_EXEC_TEST(LoadMemI32_oob_asm) {
- TestingModule module(execution_mode);
- module.origin = kAsmJsOrigin;
- int32_t* memory = module.AddMemoryElems<int32_t>(8);
- WasmRunner<int32_t> r(&module, MachineType::Uint32());
- module.RandomizeMemory(1112);
+ WasmRunner<int32_t, uint32_t> r(execution_mode);
+ r.module().ChangeOriginToAsmjs();
+ int32_t* memory = r.module().AddMemoryElems<int32_t>(8);
+ r.module().RandomizeMemory(1112);
BUILD(r, WASM_UNOP(kExprI32AsmjsLoadMem, WASM_GET_LOCAL(0)));
@@ -159,11 +150,10 @@ WASM_EXEC_TEST(LoadMemI32_oob_asm) {
}
WASM_EXEC_TEST(LoadMemF32_oob_asm) {
- TestingModule module(execution_mode);
- module.origin = kAsmJsOrigin;
- float* memory = module.AddMemoryElems<float>(8);
- WasmRunner<float> r(&module, MachineType::Uint32());
- module.RandomizeMemory(1112);
+ WasmRunner<float, uint32_t> r(execution_mode);
+ r.module().ChangeOriginToAsmjs();
+ float* memory = r.module().AddMemoryElems<float>(8);
+ r.module().RandomizeMemory(1112);
BUILD(r, WASM_UNOP(kExprF32AsmjsLoadMem, WASM_GET_LOCAL(0)));
@@ -180,11 +170,10 @@ WASM_EXEC_TEST(LoadMemF32_oob_asm) {
}
WASM_EXEC_TEST(LoadMemF64_oob_asm) {
- TestingModule module(execution_mode);
- module.origin = kAsmJsOrigin;
- double* memory = module.AddMemoryElems<double>(8);
- WasmRunner<double> r(&module, MachineType::Uint32());
- module.RandomizeMemory(1112);
+ WasmRunner<double, uint32_t> r(execution_mode);
+ r.module().ChangeOriginToAsmjs();
+ double* memory = r.module().AddMemoryElems<double>(8);
+ r.module().RandomizeMemory(1112);
BUILD(r, WASM_UNOP(kExprF64AsmjsLoadMem, WASM_GET_LOCAL(0)));
@@ -203,11 +192,10 @@ WASM_EXEC_TEST(LoadMemF64_oob_asm) {
}
WASM_EXEC_TEST(StoreMemI32_oob_asm) {
- TestingModule module(execution_mode);
- module.origin = kAsmJsOrigin;
- int32_t* memory = module.AddMemoryElems<int32_t>(8);
- WasmRunner<int32_t> r(&module, MachineType::Uint32(), MachineType::Uint32());
- module.RandomizeMemory(1112);
+ WasmRunner<int32_t, uint32_t, uint32_t> r(execution_mode);
+ r.module().ChangeOriginToAsmjs();
+ int32_t* memory = r.module().AddMemoryElems<int32_t>(8);
+ r.module().RandomizeMemory(1112);
BUILD(r, WASM_BINOP(kExprI32AsmjsStoreMem, WASM_GET_LOCAL(0),
WASM_GET_LOCAL(1)));
@@ -237,87 +225,78 @@ WASM_EXEC_TEST(StoreMemI32_oob_asm) {
TEST_BODY(kExprI32AsmjsStoreMem16) \
TEST_BODY(kExprI32AsmjsStoreMem)
-#define INT_LOAD_TEST(OP_TYPE) \
- TEST(RunWasm_AsmCheckedRelocInfo##OP_TYPE) { \
- TestingModule module(kExecuteCompiled); \
- module.origin = kAsmJsOrigin; \
- WasmRunner<int32_t> r(&module, MachineType::Uint32()); \
- BUILD(r, WASM_UNOP(OP_TYPE, WASM_GET_LOCAL(0))); \
- CHECK_EQ(1u, GetMatchingRelocInfoCount(module.instance->function_code[0], \
- RelocInfo::WASM_MEMORY_REFERENCE)); \
- CHECK_NE( \
- 0u, GetMatchingRelocInfoCount(module.instance->function_code[0], \
- RelocInfo::WASM_MEMORY_SIZE_REFERENCE)); \
+#define INT_LOAD_TEST(OP_TYPE) \
+ TEST(RunWasm_AsmCheckedRelocInfo##OP_TYPE) { \
+ WasmRunner<int32_t, uint32_t> r(kExecuteCompiled); \
+ r.module().ChangeOriginToAsmjs(); \
+ BUILD(r, WASM_UNOP(OP_TYPE, WASM_GET_LOCAL(0))); \
+ CHECK_EQ(1, \
+ GetMatchingRelocInfoCount(r.module().instance->function_code[0], \
+ RelocInfo::WASM_MEMORY_REFERENCE)); \
+ CHECK_NE( \
+ 0, GetMatchingRelocInfoCount(r.module().instance->function_code[0], \
+ RelocInfo::WASM_MEMORY_SIZE_REFERENCE)); \
}
FOREACH_INT_CHECKED_LOAD_OP(INT_LOAD_TEST)
-#define INT_STORE_TEST(OP_TYPE) \
- TEST(RunWasm_AsmCheckedRelocInfo##OP_TYPE) { \
- TestingModule module(kExecuteCompiled); \
- module.origin = kAsmJsOrigin; \
- WasmRunner<int32_t> r(&module, MachineType::Uint32(), \
- MachineType::Uint32()); \
- BUILD(r, WASM_BINOP(OP_TYPE, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); \
- CHECK_EQ(1u, GetMatchingRelocInfoCount(module.instance->function_code[0], \
- RelocInfo::WASM_MEMORY_REFERENCE)); \
- CHECK_NE( \
- 0u, GetMatchingRelocInfoCount(module.instance->function_code[0], \
- RelocInfo::WASM_MEMORY_SIZE_REFERENCE)); \
+#define INT_STORE_TEST(OP_TYPE) \
+ TEST(RunWasm_AsmCheckedRelocInfo##OP_TYPE) { \
+ WasmRunner<int32_t, uint32_t, uint32_t> r(kExecuteCompiled); \
+ r.module().ChangeOriginToAsmjs(); \
+ BUILD(r, WASM_BINOP(OP_TYPE, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); \
+ CHECK_EQ(1, \
+ GetMatchingRelocInfoCount(r.module().instance->function_code[0], \
+ RelocInfo::WASM_MEMORY_REFERENCE)); \
+ CHECK_NE( \
+ 0, GetMatchingRelocInfoCount(r.module().instance->function_code[0], \
+ RelocInfo::WASM_MEMORY_SIZE_REFERENCE)); \
}
FOREACH_INT_CHECKED_STORE_OP(INT_STORE_TEST)
TEST(RunWasm_AsmCheckedLoadFloat32RelocInfo) {
- TestingModule module(kExecuteCompiled);
- module.origin = kAsmJsOrigin;
- WasmRunner<float> r(&module, MachineType::Uint32());
+ WasmRunner<float, uint32_t> r(kExecuteCompiled);
+ r.module().ChangeOriginToAsmjs();
BUILD(r, WASM_UNOP(kExprF32AsmjsLoadMem, WASM_GET_LOCAL(0)));
- CHECK_EQ(1u, GetMatchingRelocInfoCount(module.instance->function_code[0],
- RelocInfo::WASM_MEMORY_REFERENCE));
- CHECK_NE(0u,
- GetMatchingRelocInfoCount(module.instance->function_code[0],
- RelocInfo::WASM_MEMORY_SIZE_REFERENCE));
+ CHECK_EQ(1, GetMatchingRelocInfoCount(r.module().instance->function_code[0],
+ RelocInfo::WASM_MEMORY_REFERENCE));
+ CHECK_NE(0, GetMatchingRelocInfoCount(r.module().instance->function_code[0],
+ RelocInfo::WASM_MEMORY_SIZE_REFERENCE));
}
TEST(RunWasm_AsmCheckedStoreFloat32RelocInfo) {
- TestingModule module(kExecuteCompiled);
- module.origin = kAsmJsOrigin;
- WasmRunner<float> r(&module, MachineType::Uint32(), MachineType::Float32());
+ WasmRunner<float, uint32_t, float> r(kExecuteCompiled);
+ r.module().ChangeOriginToAsmjs();
BUILD(r, WASM_BINOP(kExprF32AsmjsStoreMem, WASM_GET_LOCAL(0),
WASM_GET_LOCAL(1)));
- CHECK_EQ(1u, GetMatchingRelocInfoCount(module.instance->function_code[0],
- RelocInfo::WASM_MEMORY_REFERENCE));
- CHECK_NE(0u,
- GetMatchingRelocInfoCount(module.instance->function_code[0],
- RelocInfo::WASM_MEMORY_SIZE_REFERENCE));
+ CHECK_EQ(1, GetMatchingRelocInfoCount(r.module().instance->function_code[0],
+ RelocInfo::WASM_MEMORY_REFERENCE));
+ CHECK_NE(0, GetMatchingRelocInfoCount(r.module().instance->function_code[0],
+ RelocInfo::WASM_MEMORY_SIZE_REFERENCE));
}
TEST(RunWasm_AsmCheckedLoadFloat64RelocInfo) {
- TestingModule module(kExecuteCompiled);
- module.origin = kAsmJsOrigin;
- WasmRunner<double> r(&module, MachineType::Uint32());
+ WasmRunner<double, uint32_t> r(kExecuteCompiled);
+ r.module().ChangeOriginToAsmjs();
BUILD(r, WASM_UNOP(kExprF64AsmjsLoadMem, WASM_GET_LOCAL(0)));
- CHECK_EQ(1u, GetMatchingRelocInfoCount(module.instance->function_code[0],
- RelocInfo::WASM_MEMORY_REFERENCE));
- CHECK_NE(0u,
- GetMatchingRelocInfoCount(module.instance->function_code[0],
- RelocInfo::WASM_MEMORY_SIZE_REFERENCE));
+ CHECK_EQ(1, GetMatchingRelocInfoCount(r.module().instance->function_code[0],
+ RelocInfo::WASM_MEMORY_REFERENCE));
+ CHECK_NE(0, GetMatchingRelocInfoCount(r.module().instance->function_code[0],
+ RelocInfo::WASM_MEMORY_SIZE_REFERENCE));
}
TEST(RunWasm_AsmCheckedStoreFloat64RelocInfo) {
- TestingModule module(kExecuteCompiled);
- module.origin = kAsmJsOrigin;
- WasmRunner<double> r(&module, MachineType::Uint32(), MachineType::Float64());
+ WasmRunner<double, uint32_t, double> r(kExecuteCompiled);
+ r.module().ChangeOriginToAsmjs();
BUILD(r, WASM_BINOP(kExprF64AsmjsStoreMem, WASM_GET_LOCAL(0),
WASM_GET_LOCAL(1)));
- CHECK_EQ(1u, GetMatchingRelocInfoCount(module.instance->function_code[0],
- RelocInfo::WASM_MEMORY_REFERENCE));
- CHECK_NE(0u,
- GetMatchingRelocInfoCount(module.instance->function_code[0],
- RelocInfo::WASM_MEMORY_SIZE_REFERENCE));
+ CHECK_EQ(1, GetMatchingRelocInfoCount(r.module().instance->function_code[0],
+ RelocInfo::WASM_MEMORY_REFERENCE));
+ CHECK_NE(0, GetMatchingRelocInfoCount(r.module().instance->function_code[0],
+ RelocInfo::WASM_MEMORY_SIZE_REFERENCE));
}
diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-interpreter.cc b/deps/v8/test/cctest/wasm/test-run-wasm-interpreter.cc
index 47d97f4e48..e355b68d19 100644
--- a/deps/v8/test/cctest/wasm/test-run-wasm-interpreter.cc
+++ b/deps/v8/test/cctest/wasm/test-run-wasm-interpreter.cc
@@ -30,20 +30,21 @@ TEST(Run_WasmInt8Const_i) {
WasmRunner<int32_t> r(kExecuteInterpreted);
const byte kExpectedValue = 109;
// return(kExpectedValue)
- BUILD(r, WASM_I8(kExpectedValue));
+ BUILD(r, WASM_I32V_2(kExpectedValue));
CHECK_EQ(kExpectedValue, r.Call());
}
TEST(Run_WasmIfElse) {
- WasmRunner<int32_t> r(kExecuteInterpreted, MachineType::Int32());
- BUILD(r, WASM_IF_ELSE_I(WASM_GET_LOCAL(0), WASM_I8(9), WASM_I8(10)));
+ WasmRunner<int32_t, int32_t> r(kExecuteInterpreted);
+ BUILD(r, WASM_IF_ELSE_I(WASM_GET_LOCAL(0), WASM_I32V_1(9), WASM_I32V_1(10)));
CHECK_EQ(10, r.Call(0));
CHECK_EQ(9, r.Call(1));
}
TEST(Run_WasmIfReturn) {
- WasmRunner<int32_t> r(kExecuteInterpreted, MachineType::Int32());
- BUILD(r, WASM_IF(WASM_GET_LOCAL(0), WASM_RETURN1(WASM_I8(77))), WASM_I8(65));
+ WasmRunner<int32_t, int32_t> r(kExecuteInterpreted);
+ BUILD(r, WASM_IF(WASM_GET_LOCAL(0), WASM_RETURN1(WASM_I32V_2(77))),
+ WASM_I32V_2(65));
CHECK_EQ(65, r.Call(0));
CHECK_EQ(77, r.Call(1));
}
@@ -54,7 +55,7 @@ TEST(Run_WasmNopsN) {
for (int nops = 0; nops < kMaxNops; nops++) {
byte expected = static_cast<byte>(20 + nops);
memset(code, kExprNop, sizeof(code));
- code[nops] = kExprI8Const;
+ code[nops] = kExprI32Const;
code[nops + 1] = expected;
WasmRunner<int32_t> r(kExecuteInterpreted);
@@ -64,13 +65,13 @@ TEST(Run_WasmNopsN) {
}
TEST(Run_WasmConstsN) {
- const int kMaxConsts = 10;
+ const int kMaxConsts = 5;
byte code[kMaxConsts * 3];
int32_t expected = 0;
for (int count = 1; count < kMaxConsts; count++) {
for (int i = 0; i < count; i++) {
byte val = static_cast<byte>(count * 10 + i);
- code[i * 3] = kExprI8Const;
+ code[i * 3] = kExprI32Const;
code[i * 3 + 1] = val;
if (i == (count - 1)) {
code[i * 3 + 2] = kExprNop;
@@ -95,7 +96,7 @@ TEST(Run_WasmBlocksN) {
memset(code, kExprNop, sizeof(code));
code[0] = kExprBlock;
code[1] = kLocalI32;
- code[2 + nops] = kExprI8Const;
+ code[2 + nops] = kExprI32Const;
code[2 + nops + 1] = expected;
code[2 + nops + 2] = kExprEnd;
@@ -108,6 +109,7 @@ TEST(Run_WasmBlocksN) {
TEST(Run_WasmBlockBreakN) {
const int kMaxNops = 10;
const int kExtra = 6;
+ int run = 0;
byte code[kMaxNops + kExtra];
for (int nops = 0; nops < kMaxNops; nops++) {
// Place the break anywhere within the block.
@@ -117,8 +119,8 @@ TEST(Run_WasmBlockBreakN) {
code[1] = kLocalI32;
code[sizeof(code) - 1] = kExprEnd;
- int expected = nops * 11 + index;
- code[2 + index + 0] = kExprI8Const;
+ int expected = run++;
+ code[2 + index + 0] = kExprI32Const;
code[2 + index + 1] = static_cast<byte>(expected);
code[2 + index + 2] = kExprBr;
code[2 + index + 3] = 0;
@@ -131,13 +133,14 @@ TEST(Run_WasmBlockBreakN) {
}
TEST(Run_Wasm_nested_ifs_i) {
- WasmRunner<int32_t> r(kExecuteInterpreted, MachineType::Int32(),
- MachineType::Int32());
+ WasmRunner<int32_t, int32_t, int32_t> r(kExecuteInterpreted);
- BUILD(r, WASM_IF_ELSE_I(
- WASM_GET_LOCAL(0),
- WASM_IF_ELSE_I(WASM_GET_LOCAL(1), WASM_I8(11), WASM_I8(12)),
- WASM_IF_ELSE_I(WASM_GET_LOCAL(1), WASM_I8(13), WASM_I8(14))));
+ BUILD(
+ r,
+ WASM_IF_ELSE_I(
+ WASM_GET_LOCAL(0),
+ WASM_IF_ELSE_I(WASM_GET_LOCAL(1), WASM_I32V_1(11), WASM_I32V_1(12)),
+ WASM_IF_ELSE_I(WASM_GET_LOCAL(1), WASM_I32V_1(13), WASM_I32V_1(14))));
CHECK_EQ(11, r.Call(1, 1));
CHECK_EQ(12, r.Call(1, 0));
@@ -180,8 +183,7 @@ TEST(Breakpoint_I32Add) {
Find(code, sizeof(code), kNumBreakpoints, kExprGetLocal, kExprGetLocal,
kExprI32Add);
- WasmRunner<int32_t> r(kExecuteInterpreted, MachineType::Uint32(),
- MachineType::Uint32());
+ WasmRunner<int32_t, uint32_t, uint32_t> r(kExecuteInterpreted);
r.Build(code, code + arraysize(code));
@@ -217,11 +219,10 @@ TEST(Breakpoint_I32Add) {
}
TEST(Step_I32Mul) {
- static const int kTraceLength = 4;
+ static const int kTraceLength = 5;
byte code[] = {WASM_I32_MUL(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))};
- WasmRunner<int32_t> r(kExecuteInterpreted, MachineType::Uint32(),
- MachineType::Uint32());
+ WasmRunner<int32_t, uint32_t, uint32_t> r(kExecuteInterpreted);
r.Build(code, code + arraysize(code));
@@ -259,8 +260,7 @@ TEST(Breakpoint_I32And_disable) {
std::unique_ptr<int[]> offsets =
Find(code, sizeof(code), kNumBreakpoints, kExprI32And);
- WasmRunner<int32_t> r(kExecuteInterpreted, MachineType::Uint32(),
- MachineType::Uint32());
+ WasmRunner<int32_t, uint32_t, uint32_t> r(kExecuteInterpreted);
r.Build(code, code + arraysize(code));
@@ -297,19 +297,27 @@ TEST(Breakpoint_I32And_disable) {
}
TEST(GrowMemory) {
- TestingModule module(kExecuteInterpreted);
- WasmRunner<int32_t> r(&module, MachineType::Uint32());
- module.AddMemory(WasmModule::kPageSize);
- BUILD(r, WASM_GROW_MEMORY(WASM_GET_LOCAL(0)));
- CHECK_EQ(1, r.Call(1));
+ {
+ WasmRunner<int32_t, uint32_t> r(kExecuteInterpreted);
+ r.module().AddMemory(WasmModule::kPageSize);
+ r.module().SetMaxMemPages(10);
+ BUILD(r, WASM_GROW_MEMORY(WASM_GET_LOCAL(0)));
+ CHECK_EQ(1, r.Call(1));
+ }
+ {
+ WasmRunner<int32_t, uint32_t> r(kExecuteInterpreted);
+ r.module().AddMemory(WasmModule::kPageSize);
+ r.module().SetMaxMemPages(10);
+ BUILD(r, WASM_GROW_MEMORY(WASM_GET_LOCAL(0)));
+ CHECK_EQ(-1, r.Call(11));
+ }
}
TEST(GrowMemoryPreservesData) {
int32_t index = 16;
int32_t value = 2335;
- TestingModule module(kExecuteInterpreted);
- WasmRunner<int32_t> r(&module, MachineType::Uint32());
- module.AddMemory(WasmModule::kPageSize);
+ WasmRunner<int32_t, uint32_t> r(kExecuteInterpreted);
+ r.module().AddMemory(WasmModule::kPageSize);
BUILD(r, WASM_STORE_MEM(MachineType::Int32(), WASM_I32V(index),
WASM_I32V(value)),
WASM_GROW_MEMORY(WASM_GET_LOCAL(0)), WASM_DROP,
@@ -320,16 +328,14 @@ TEST(GrowMemoryPreservesData) {
TEST(GrowMemoryInvalidSize) {
{
// Grow memory by an invalid amount without initial memory.
- TestingModule module(kExecuteInterpreted);
- WasmRunner<int32_t> r(&module, MachineType::Uint32());
+ WasmRunner<int32_t, uint32_t> r(kExecuteInterpreted);
BUILD(r, WASM_GROW_MEMORY(WASM_GET_LOCAL(0)));
CHECK_EQ(-1, r.Call(1048575));
}
{
// Grow memory by an invalid amount without initial memory.
- TestingModule module(kExecuteInterpreted);
- WasmRunner<int32_t> r(&module, MachineType::Uint32());
- module.AddMemory(WasmModule::kPageSize);
+ WasmRunner<int32_t, uint32_t> r(kExecuteInterpreted);
+ r.module().AddMemory(WasmModule::kPageSize);
BUILD(r, WASM_GROW_MEMORY(WASM_GET_LOCAL(0)));
CHECK_EQ(-1, r.Call(1048575));
}
@@ -338,9 +344,7 @@ TEST(GrowMemoryInvalidSize) {
TEST(TestPossibleNondeterminism) {
{
// F32Div may produced NaN
- TestingModule module(kExecuteInterpreted);
- WasmRunner<float> r(&module, MachineType::Float32(),
- MachineType::Float32());
+ WasmRunner<float, float, float> r(kExecuteInterpreted);
BUILD(r, WASM_F32_DIV(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
r.Call(1048575.5f, 2.5f);
CHECK(!r.possible_nondeterminism());
@@ -349,8 +353,7 @@ TEST(TestPossibleNondeterminism) {
}
{
// F32Sqrt may produced NaN
- TestingModule module(kExecuteInterpreted);
- WasmRunner<float> r(&module, MachineType::Float32());
+ WasmRunner<float, float> r(kExecuteInterpreted);
BUILD(r, WASM_F32_SQRT(WASM_GET_LOCAL(0)));
r.Call(16.0f);
CHECK(!r.possible_nondeterminism());
@@ -359,9 +362,7 @@ TEST(TestPossibleNondeterminism) {
}
{
// F32Mul may produced NaN
- TestingModule module(kExecuteInterpreted);
- WasmRunner<float> r(&module, MachineType::Float32(),
- MachineType::Float32());
+ WasmRunner<float, float, float> r(kExecuteInterpreted);
BUILD(r, WASM_F32_MUL(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
r.Call(1048575.5f, 2.5f);
CHECK(!r.possible_nondeterminism());
@@ -370,9 +371,7 @@ TEST(TestPossibleNondeterminism) {
}
{
// F64Div may produced NaN
- TestingModule module(kExecuteInterpreted);
- WasmRunner<double> r(&module, MachineType::Float64(),
- MachineType::Float64());
+ WasmRunner<double, double, double> r(kExecuteInterpreted);
BUILD(r, WASM_F64_DIV(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
r.Call(1048575.5, 2.5);
CHECK(!r.possible_nondeterminism());
@@ -381,8 +380,7 @@ TEST(TestPossibleNondeterminism) {
}
{
// F64Sqrt may produced NaN
- TestingModule module(kExecuteInterpreted);
- WasmRunner<double> r(&module, MachineType::Float64());
+ WasmRunner<double, double> r(kExecuteInterpreted);
BUILD(r, WASM_F64_SQRT(WASM_GET_LOCAL(0)));
r.Call(1048575.5);
CHECK(!r.possible_nondeterminism());
@@ -391,9 +389,7 @@ TEST(TestPossibleNondeterminism) {
}
{
// F64Mul may produced NaN
- TestingModule module(kExecuteInterpreted);
- WasmRunner<double> r(&module, MachineType::Float64(),
- MachineType::Float64());
+ WasmRunner<double, double, double> r(kExecuteInterpreted);
BUILD(r, WASM_F64_MUL(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
r.Call(1048575.5, 2.5);
CHECK(!r.possible_nondeterminism());
diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-js.cc b/deps/v8/test/cctest/wasm/test-run-wasm-js.cc
index 4a74128f50..ee6b066282 100644
--- a/deps/v8/test/cctest/wasm/test-run-wasm-js.cc
+++ b/deps/v8/test/cctest/wasm/test-run-wasm-js.cc
@@ -97,48 +97,36 @@ void EXPECT_CALL(double expected, Handle<JSFunction> jsfunc, double a,
} // namespace
TEST(Run_Int32Sub_jswrapped) {
- CcTest::InitializeVM();
- TestSignatures sigs;
- TestingModule module;
- WasmFunctionCompiler t(sigs.i_ii(), &module);
- BUILD(t, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
- Handle<JSFunction> jsfunc = module.WrapCode(t.CompileAndAdd());
+ WasmRunner<int, int, int> r(kExecuteCompiled);
+ BUILD(r, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
+ Handle<JSFunction> jsfunc = r.module().WrapCode(r.function()->func_index);
EXPECT_CALL(33, jsfunc, 44, 11);
EXPECT_CALL(-8723487, jsfunc, -8000000, 723487);
}
TEST(Run_Float32Div_jswrapped) {
- CcTest::InitializeVM();
- TestSignatures sigs;
- TestingModule module;
- WasmFunctionCompiler t(sigs.f_ff(), &module);
- BUILD(t, WASM_F32_DIV(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
- Handle<JSFunction> jsfunc = module.WrapCode(t.CompileAndAdd());
+ WasmRunner<float, float, float> r(kExecuteCompiled);
+ BUILD(r, WASM_F32_DIV(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
+ Handle<JSFunction> jsfunc = r.module().WrapCode(r.function()->func_index);
EXPECT_CALL(92, jsfunc, 46, 0.5);
EXPECT_CALL(64, jsfunc, -16, -0.25);
}
TEST(Run_Float64Add_jswrapped) {
- CcTest::InitializeVM();
- TestSignatures sigs;
- TestingModule module;
- WasmFunctionCompiler t(sigs.d_dd(), &module);
- BUILD(t, WASM_F64_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
- Handle<JSFunction> jsfunc = module.WrapCode(t.CompileAndAdd());
+ WasmRunner<double, double, double> r(kExecuteCompiled);
+ BUILD(r, WASM_F64_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
+ Handle<JSFunction> jsfunc = r.module().WrapCode(r.function()->func_index);
EXPECT_CALL(3, jsfunc, 2, 1);
EXPECT_CALL(-5.5, jsfunc, -5.25, -0.25);
}
TEST(Run_I32Popcount_jswrapped) {
- CcTest::InitializeVM();
- TestSignatures sigs;
- TestingModule module;
- WasmFunctionCompiler t(sigs.i_i(), &module);
- BUILD(t, WASM_I32_POPCNT(WASM_GET_LOCAL(0)));
- Handle<JSFunction> jsfunc = module.WrapCode(t.CompileAndAdd());
+ WasmRunner<int, int> r(kExecuteCompiled);
+ BUILD(r, WASM_I32_POPCNT(WASM_GET_LOCAL(0)));
+ Handle<JSFunction> jsfunc = r.module().WrapCode(r.function()->func_index);
EXPECT_CALL(2, jsfunc, 9, 0);
EXPECT_CALL(3, jsfunc, 11, 0);
@@ -146,15 +134,13 @@ TEST(Run_I32Popcount_jswrapped) {
}
TEST(Run_CallJS_Add_jswrapped) {
- CcTest::InitializeVM();
+ WasmRunner<int, int> r(kExecuteCompiled);
TestSignatures sigs;
- TestingModule module;
- WasmFunctionCompiler t(sigs.i_i(), &module);
uint32_t js_index =
- module.AddJsFunction(sigs.i_i(), "(function(a) { return a + 99; })");
- BUILD(t, WASM_CALL_FUNCTION(js_index, WASM_GET_LOCAL(0)));
+ r.module().AddJsFunction(sigs.i_i(), "(function(a) { return a + 99; })");
+ BUILD(r, WASM_CALL_FUNCTION(js_index, WASM_GET_LOCAL(0)));
- Handle<JSFunction> jsfunc = module.WrapCode(t.CompileAndAdd());
+ Handle<JSFunction> jsfunc = r.module().WrapCode(r.function()->func_index);
EXPECT_CALL(101, jsfunc, 2, -8);
EXPECT_CALL(199, jsfunc, 100, -1);
@@ -164,16 +150,16 @@ TEST(Run_CallJS_Add_jswrapped) {
void RunJSSelectTest(int which) {
const int kMaxParams = 8;
PredictableInputValues inputs(0x100);
- LocalType type = kAstF64;
- LocalType types[kMaxParams + 1] = {type, type, type, type, type,
+ ValueType type = kWasmF64;
+ ValueType types[kMaxParams + 1] = {type, type, type, type, type,
type, type, type, type};
for (int num_params = which + 1; num_params < kMaxParams; num_params++) {
HandleScope scope(CcTest::InitIsolateOnce());
FunctionSig sig(1, num_params, types);
- TestingModule module;
- uint32_t js_index = AddJSSelector(&module, &sig, which);
- WasmFunctionCompiler t(&sig, &module);
+ WasmRunner<void> r(kExecuteCompiled);
+ uint32_t js_index = AddJSSelector(&r.module(), &sig, which);
+ WasmFunctionCompiler& t = r.NewFunction(&sig);
{
std::vector<byte> code;
@@ -189,7 +175,7 @@ void RunJSSelectTest(int which) {
t.Build(&code[0], &code[end]);
}
- Handle<JSFunction> jsfunc = module.WrapCode(t.CompileAndAdd());
+ Handle<JSFunction> jsfunc = r.module().WrapCode(t.function_index());
double expected = inputs.arg_d(which);
EXPECT_CALL(expected, jsfunc, 0.0, 0.0);
}
@@ -240,15 +226,15 @@ void RunWASMSelectTest(int which) {
Isolate* isolate = CcTest::InitIsolateOnce();
const int kMaxParams = 8;
for (int num_params = which + 1; num_params < kMaxParams; num_params++) {
- LocalType type = kAstF64;
- LocalType types[kMaxParams + 1] = {type, type, type, type, type,
+ ValueType type = kWasmF64;
+ ValueType types[kMaxParams + 1] = {type, type, type, type, type,
type, type, type, type};
FunctionSig sig(1, num_params, types);
- TestingModule module;
- WasmFunctionCompiler t(&sig, &module);
+ WasmRunner<void> r(kExecuteCompiled);
+ WasmFunctionCompiler& t = r.NewFunction(&sig);
BUILD(t, WASM_GET_LOCAL(which));
- Handle<JSFunction> jsfunc = module.WrapCode(t.CompileAndAdd());
+ Handle<JSFunction> jsfunc = r.module().WrapCode(t.function_index());
Handle<Object> args[] = {
isolate->factory()->NewNumber(inputs.arg_d(0)),
@@ -311,16 +297,16 @@ void RunWASMSelectAlignTest(int num_args, int num_params) {
Isolate* isolate = CcTest::InitIsolateOnce();
const int kMaxParams = 10;
DCHECK_LE(num_args, kMaxParams);
- LocalType type = kAstF64;
- LocalType types[kMaxParams + 1] = {type, type, type, type, type, type,
+ ValueType type = kWasmF64;
+ ValueType types[kMaxParams + 1] = {type, type, type, type, type, type,
type, type, type, type, type};
FunctionSig sig(1, num_params, types);
for (int which = 0; which < num_params; which++) {
- TestingModule module;
- WasmFunctionCompiler t(&sig, &module);
+ WasmRunner<void> r(kExecuteCompiled);
+ WasmFunctionCompiler& t = r.NewFunction(&sig);
BUILD(t, WASM_GET_LOCAL(which));
- Handle<JSFunction> jsfunc = module.WrapCode(t.CompileAndAdd());
+ Handle<JSFunction> jsfunc = r.module().WrapCode(t.function_index());
Handle<Object> args[] = {isolate->factory()->NewNumber(inputs.arg_d(0)),
isolate->factory()->NewNumber(inputs.arg_d(1)),
@@ -407,10 +393,12 @@ void RunJSSelectAlignTest(int num_args, int num_params) {
const int kMaxParams = 10;
CHECK_LE(num_args, kMaxParams);
CHECK_LE(num_params, kMaxParams);
- LocalType type = kAstF64;
- LocalType types[kMaxParams + 1] = {type, type, type, type, type, type,
+ ValueType type = kWasmF64;
+ ValueType types[kMaxParams + 1] = {type, type, type, type, type, type,
type, type, type, type, type};
FunctionSig sig(1, num_params, types);
+ i::AccountingAllocator allocator;
+ Zone zone(&allocator, ZONE_NAME);
// Build the calling code.
std::vector<byte> code;
@@ -419,21 +407,21 @@ void RunJSSelectAlignTest(int num_args, int num_params) {
ADD_CODE(code, WASM_GET_LOCAL(i));
}
- ADD_CODE(code, kExprCallFunction, 0);
+ uint8_t predicted_js_index = 1;
+ ADD_CODE(code, kExprCallFunction, predicted_js_index);
size_t end = code.size();
code.push_back(0);
// Call different select JS functions.
for (int which = 0; which < num_params; which++) {
- HandleScope scope(isolate);
- TestingModule module;
- uint32_t js_index = AddJSSelector(&module, &sig, which);
- CHECK_EQ(0u, js_index);
- WasmFunctionCompiler t(&sig, &module);
+ WasmRunner<void> r(kExecuteCompiled);
+ uint32_t js_index = AddJSSelector(&r.module(), &sig, which);
+ CHECK_EQ(predicted_js_index, js_index);
+ WasmFunctionCompiler& t = r.NewFunction(&sig);
t.Build(&code[0], &code[end]);
- Handle<JSFunction> jsfunc = module.WrapCode(t.CompileAndAdd());
+ Handle<JSFunction> jsfunc = r.module().WrapCode(t.function_index());
Handle<Object> args[] = {
factory->NewNumber(inputs.arg_d(0)),
diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-module.cc b/deps/v8/test/cctest/wasm/test-run-wasm-module.cc
index 94054bd388..468dc81159 100644
--- a/deps/v8/test/cctest/wasm/test-run-wasm-module.cc
+++ b/deps/v8/test/cctest/wasm/test-run-wasm-module.cc
@@ -63,6 +63,12 @@ void TestModuleException(Zone* zone, WasmModuleBuilder* builder) {
void ExportAsMain(WasmFunctionBuilder* f) { f->ExportAs(CStrVector("main")); }
+#define EMIT_CODE_WITH_END(f, code) \
+ do { \
+ f->EmitCode(code, sizeof(code)); \
+ f->Emit(kExprEnd); \
+ } while (false)
+
} // namespace
TEST(Run_WasmModule_Return114) {
@@ -75,8 +81,8 @@ TEST(Run_WasmModule_Return114) {
WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
ExportAsMain(f);
- byte code[] = {WASM_I8(kReturnValue)};
- f->EmitCode(code, sizeof(code));
+ byte code[] = {WASM_I32V_2(kReturnValue)};
+ EMIT_CODE_WITH_END(f, code);
TestModule(&zone, builder, kReturnValue);
}
Cleanup();
@@ -95,14 +101,14 @@ TEST(Run_WasmModule_CallAdd) {
uint16_t param2 = 1;
byte code1[] = {
WASM_I32_ADD(WASM_GET_LOCAL(param1), WASM_GET_LOCAL(param2))};
- f1->EmitCode(code1, sizeof(code1));
+ EMIT_CODE_WITH_END(f1, code1);
WasmFunctionBuilder* f2 = builder->AddFunction(sigs.i_v());
ExportAsMain(f2);
byte code2[] = {
- WASM_CALL_FUNCTION(f1->func_index(), WASM_I8(77), WASM_I8(22))};
- f2->EmitCode(code2, sizeof(code2));
+ WASM_CALL_FUNCTION(f1->func_index(), WASM_I32V_2(77), WASM_I32V_1(22))};
+ EMIT_CODE_WITH_END(f2, code2);
TestModule(&zone, builder, 99);
}
Cleanup();
@@ -120,8 +126,8 @@ TEST(Run_WasmModule_ReadLoadedDataSegment) {
ExportAsMain(f);
byte code[] = {
- WASM_LOAD_MEM(MachineType::Int32(), WASM_I8(kDataSegmentDest0))};
- f->EmitCode(code, sizeof(code));
+ WASM_LOAD_MEM(MachineType::Int32(), WASM_I32V_1(kDataSegmentDest0))};
+ EMIT_CODE_WITH_END(f, code);
byte data[] = {0xaa, 0xbb, 0xcc, 0xdd};
builder->AddDataSegment(data, sizeof(data), kDataSegmentDest0);
TestModule(&zone, builder, 0xddccbbaa);
@@ -139,16 +145,17 @@ TEST(Run_WasmModule_CheckMemoryIsZero) {
WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
- uint16_t localIndex = f->AddLocal(kAstI32);
+ uint16_t localIndex = f->AddLocal(kWasmI32);
ExportAsMain(f);
byte code[] = {WASM_BLOCK_I(
WASM_WHILE(
WASM_I32_LTS(WASM_GET_LOCAL(localIndex), WASM_I32V_3(kCheckSize)),
WASM_IF_ELSE(
WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(localIndex)),
- WASM_BRV(3, WASM_I8(-1)), WASM_INC_LOCAL_BY(localIndex, 4))),
- WASM_I8(11))};
- f->EmitCode(code, sizeof(code));
+ WASM_BRV(3, WASM_I32V_1(-1)),
+ WASM_INC_LOCAL_BY(localIndex, 4))),
+ WASM_I32V_1(11))};
+ EMIT_CODE_WITH_END(f, code);
TestModule(&zone, builder, 11);
}
Cleanup();
@@ -163,17 +170,17 @@ TEST(Run_WasmModule_CallMain_recursive) {
WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
- uint16_t localIndex = f->AddLocal(kAstI32);
+ uint16_t localIndex = f->AddLocal(kWasmI32);
ExportAsMain(f);
byte code[] = {
WASM_SET_LOCAL(localIndex,
WASM_LOAD_MEM(MachineType::Int32(), WASM_ZERO)),
- WASM_IF_ELSE_I(WASM_I32_LTS(WASM_GET_LOCAL(localIndex), WASM_I8(5)),
+ WASM_IF_ELSE_I(WASM_I32_LTS(WASM_GET_LOCAL(localIndex), WASM_I32V_1(5)),
WASM_SEQ(WASM_STORE_MEM(MachineType::Int32(), WASM_ZERO,
WASM_INC_LOCAL(localIndex)),
WASM_CALL_FUNCTION0(0)),
- WASM_I8(55))};
- f->EmitCode(code, sizeof(code));
+ WASM_I32V_1(55))};
+ EMIT_CODE_WITH_END(f, code);
TestModule(&zone, builder, 55);
}
Cleanup();
@@ -186,18 +193,18 @@ TEST(Run_WasmModule_Global) {
TestSignatures sigs;
WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
- uint32_t global1 = builder->AddGlobal(kAstI32, 0);
- uint32_t global2 = builder->AddGlobal(kAstI32, 0);
+ uint32_t global1 = builder->AddGlobal(kWasmI32, 0);
+ uint32_t global2 = builder->AddGlobal(kWasmI32, 0);
WasmFunctionBuilder* f1 = builder->AddFunction(sigs.i_v());
byte code1[] = {
WASM_I32_ADD(WASM_GET_GLOBAL(global1), WASM_GET_GLOBAL(global2))};
- f1->EmitCode(code1, sizeof(code1));
+ EMIT_CODE_WITH_END(f1, code1);
WasmFunctionBuilder* f2 = builder->AddFunction(sigs.i_v());
ExportAsMain(f2);
byte code2[] = {WASM_SET_GLOBAL(global1, WASM_I32V_1(56)),
WASM_SET_GLOBAL(global2, WASM_I32V_1(41)),
WASM_RETURN1(WASM_CALL_FUNCTION0(f1->func_index()))};
- f2->EmitCode(code2, sizeof(code2));
+ EMIT_CODE_WITH_END(f2, code2);
TestModule(&zone, builder, 97);
}
Cleanup();
@@ -211,6 +218,18 @@ class WasmSerializationTest {
SetUp();
}
+ static void BuildWireBytes(Zone* zone, ZoneBuffer* buffer) {
+ WasmModuleBuilder* builder = new (zone) WasmModuleBuilder(zone);
+ TestSignatures sigs;
+
+ WasmFunctionBuilder* f = builder->AddFunction(sigs.i_i());
+ byte code[] = {WASM_GET_LOCAL(0), kExprI32Const, 1, kExprI32Add};
+ EMIT_CODE_WITH_END(f, code);
+ f->ExportAs(CStrVector(kFunctionName));
+
+ builder->WriteTo(*buffer);
+ }
+
void ClearSerializedData() {
serialized_bytes_.first = nullptr;
serialized_bytes_.second = 0;
@@ -239,8 +258,8 @@ class WasmSerializationTest {
ErrorThrower thrower(current_isolate(), "");
v8::Local<v8::WasmCompiledModule> deserialized_module;
CHECK(Deserialize().ToLocal(&deserialized_module));
- Handle<JSObject> module_object =
- Handle<JSObject>::cast(v8::Utils::OpenHandle(*deserialized_module));
+ Handle<WasmModuleObject> module_object = Handle<WasmModuleObject>::cast(
+ v8::Utils::OpenHandle(*deserialized_module));
{
DisallowHeapAllocation assume_no_gc;
Handle<WasmCompiledModule> compiled_part(
@@ -272,6 +291,8 @@ class WasmSerializationTest {
TearDown();
}
+ v8::Isolate* current_isolate_v8() { return current_isolate_v8_; }
+
private:
static const char* kFunctionName;
@@ -284,19 +305,17 @@ class WasmSerializationTest {
return serialized_bytes_;
}
- v8::Isolate* current_isolate_v8() { return current_isolate_v8_; }
-
void SetUp() {
WasmModuleBuilder* builder = new (zone()) WasmModuleBuilder(zone());
TestSignatures sigs;
WasmFunctionBuilder* f = builder->AddFunction(sigs.i_i());
byte code[] = {WASM_GET_LOCAL(0), kExprI32Const, 1, kExprI32Add};
- f->EmitCode(code, sizeof(code));
+ EMIT_CODE_WITH_END(f, code);
f->ExportAs(CStrVector(kFunctionName));
ZoneBuffer buffer(&zone_);
- builder->WriteTo(buffer);
+ WasmSerializationTest::BuildWireBytes(zone(), &buffer);
Isolate* serialization_isolate = CcTest::InitIsolateOnce();
ErrorThrower thrower(serialization_isolate, "");
@@ -315,8 +334,10 @@ class WasmSerializationTest {
serialization_isolate, const_cast<WasmModule*>(decoding_result.val));
MaybeHandle<WasmCompiledModule> compiled_module =
- decoding_result.val->CompileFunctions(serialization_isolate,
- module_wrapper, &thrower);
+ decoding_result.val->CompileFunctions(
+ serialization_isolate, module_wrapper, &thrower,
+ ModuleWireBytes(buffer.begin(), buffer.end()),
+ Handle<Script>::null(), Vector<const byte>::empty());
CHECK(!compiled_module.is_null());
Handle<JSObject> module_obj = WasmModuleObject::New(
serialization_isolate, compiled_module.ToHandleChecked());
@@ -410,6 +431,40 @@ TEST(DeserializeWireBytesAndSerializedDataInvalid) {
Cleanup();
}
+bool False(v8::Local<v8::Context> context) { return false; }
+
+TEST(BlockWasmCodeGen) {
+ v8::internal::AccountingAllocator allocator;
+ Zone zone(&allocator, ZONE_NAME);
+ ZoneBuffer buffer(&zone);
+ WasmSerializationTest::BuildWireBytes(&zone, &buffer);
+ Isolate* isolate = CcTest::InitIsolateOnce();
+ HandleScope scope(isolate);
+ testing::SetupIsolateForWasmModule(isolate);
+ CcTest::isolate()->SetAllowCodeGenerationFromStringsCallback(False);
+
+ ErrorThrower thrower(isolate, "block codegen");
+ MaybeHandle<WasmModuleObject> ret = wasm::CreateModuleObjectFromBytes(
+ isolate, buffer.begin(), buffer.end(), &thrower,
+ wasm::ModuleOrigin::kWasmOrigin, Handle<v8::internal::Script>::null(),
+ Vector<const byte>::empty());
+ CcTest::isolate()->SetAllowCodeGenerationFromStringsCallback(nullptr);
+ CHECK(ret.is_null());
+ CHECK(thrower.error());
+}
+
+TEST(BlockWasmCodeGenAtDeserialization) {
+ WasmSerializationTest test;
+ {
+ HandleScope scope(test.current_isolate());
+ test.current_isolate_v8()->SetAllowCodeGenerationFromStringsCallback(False);
+ v8::MaybeLocal<v8::WasmCompiledModule> nothing = test.Deserialize();
+ CHECK(nothing.IsEmpty());
+ }
+ Cleanup(test.current_isolate());
+ Cleanup();
+}
+
TEST(MemorySize) {
{
// Initial memory size is 16, see wasm-module-builder.cc
@@ -422,7 +477,7 @@ TEST(MemorySize) {
WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
ExportAsMain(f);
byte code[] = {WASM_MEMORY_SIZE};
- f->EmitCode(code, sizeof(code));
+ EMIT_CODE_WITH_END(f, code);
TestModule(&zone, builder, kExpectedValue);
}
Cleanup();
@@ -439,8 +494,9 @@ TEST(Run_WasmModule_MemSize_GrowMem) {
WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
ExportAsMain(f);
- byte code[] = {WASM_GROW_MEMORY(WASM_I8(10)), WASM_DROP, WASM_MEMORY_SIZE};
- f->EmitCode(code, sizeof(code));
+ byte code[] = {WASM_GROW_MEMORY(WASM_I32V_1(10)), WASM_DROP,
+ WASM_MEMORY_SIZE};
+ EMIT_CODE_WITH_END(f, code);
TestModule(&zone, builder, kExpectedValue);
}
Cleanup();
@@ -458,7 +514,7 @@ TEST(GrowMemoryZero) {
WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
ExportAsMain(f);
byte code[] = {WASM_GROW_MEMORY(WASM_I32V(0))};
- f->EmitCode(code, sizeof(code));
+ EMIT_CODE_WITH_END(f, code);
TestModule(&zone, builder, kExpectedValue);
}
Cleanup();
@@ -529,14 +585,14 @@ TEST(TestInterruptLoop) {
WASM_I32V(InterruptThread::signal_value_)),
WASM_BR(1))),
WASM_I32V(121)};
- f->EmitCode(code, sizeof(code));
+ EMIT_CODE_WITH_END(f, code);
ZoneBuffer buffer(&zone);
builder->WriteTo(buffer);
HandleScope scope(isolate);
testing::SetupIsolateForWasmModule(isolate);
ErrorThrower thrower(isolate, "Test");
- const Handle<JSObject> instance =
+ const Handle<WasmInstanceObject> instance =
testing::CompileInstantiateWasmModuleForTesting(
isolate, &thrower, buffer.begin(), buffer.end(),
ModuleOrigin::kWasmOrigin);
@@ -568,7 +624,7 @@ TEST(Run_WasmModule_GrowMemoryInIf) {
ExportAsMain(f);
byte code[] = {WASM_IF_ELSE_I(WASM_I32V(0), WASM_GROW_MEMORY(WASM_I32V(1)),
WASM_I32V(12))};
- f->EmitCode(code, sizeof(code));
+ EMIT_CODE_WITH_END(f, code);
TestModule(&zone, builder, 12);
}
Cleanup();
@@ -587,10 +643,10 @@ TEST(Run_WasmModule_GrowMemOobOffset) {
WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
ExportAsMain(f);
- byte code[] = {WASM_GROW_MEMORY(WASM_I8(1)),
+ byte code[] = {WASM_GROW_MEMORY(WASM_I32V_1(1)),
WASM_STORE_MEM(MachineType::Int32(), WASM_I32V(index),
WASM_I32V(value))};
- f->EmitCode(code, sizeof(code));
+ EMIT_CODE_WITH_END(f, code);
TestModuleException(&zone, builder);
}
Cleanup();
@@ -613,7 +669,7 @@ TEST(Run_WasmModule_GrowMemOobFixedIndex) {
WASM_STORE_MEM(MachineType::Int32(), WASM_I32V(index),
WASM_I32V(value)),
WASM_LOAD_MEM(MachineType::Int32(), WASM_I32V(index))};
- f->EmitCode(code, sizeof(code));
+ EMIT_CODE_WITH_END(f, code);
HandleScope scope(isolate);
ZoneBuffer buffer(&zone);
@@ -657,11 +713,11 @@ TEST(Run_WasmModule_GrowMemOobVariableIndex) {
WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
WasmFunctionBuilder* f = builder->AddFunction(sigs.i_i());
ExportAsMain(f);
- byte code[] = {WASM_GROW_MEMORY(WASM_I8(1)), WASM_DROP,
+ byte code[] = {WASM_GROW_MEMORY(WASM_I32V_1(1)), WASM_DROP,
WASM_STORE_MEM(MachineType::Int32(), WASM_GET_LOCAL(0),
WASM_I32V(value)),
WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(0))};
- f->EmitCode(code, sizeof(code));
+ EMIT_CODE_WITH_END(f, code);
HandleScope scope(isolate);
ZoneBuffer buffer(&zone);
@@ -714,13 +770,13 @@ TEST(Run_WasmModule_Global_init) {
WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
uint32_t global1 =
- builder->AddGlobal(kAstI32, false, false, WasmInitExpr(777777));
+ builder->AddGlobal(kWasmI32, false, false, WasmInitExpr(777777));
uint32_t global2 =
- builder->AddGlobal(kAstI32, false, false, WasmInitExpr(222222));
+ builder->AddGlobal(kWasmI32, false, false, WasmInitExpr(222222));
WasmFunctionBuilder* f1 = builder->AddFunction(sigs.i_v());
byte code[] = {
WASM_I32_ADD(WASM_GET_GLOBAL(global1), WASM_GET_GLOBAL(global2))};
- f1->EmitCode(code, sizeof(code));
+ EMIT_CODE_WITH_END(f1, code);
ExportAsMain(f1);
TestModule(&zone, builder, 999999);
}
@@ -728,13 +784,13 @@ TEST(Run_WasmModule_Global_init) {
}
template <typename CType>
-static void RunWasmModuleGlobalInitTest(LocalType type, CType expected) {
+static void RunWasmModuleGlobalInitTest(ValueType type, CType expected) {
{
v8::internal::AccountingAllocator allocator;
Zone zone(&allocator, ZONE_NAME);
TestSignatures sigs;
- LocalType types[] = {type};
+ ValueType types[] = {type};
FunctionSig sig(1, 0, types);
for (int padding = 0; padding < 5; padding++) {
@@ -742,17 +798,17 @@ static void RunWasmModuleGlobalInitTest(LocalType type, CType expected) {
WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
for (int i = 0; i < padding; i++) { // pad global before
- builder->AddGlobal(kAstI32, false, false, WasmInitExpr(i + 20000));
+ builder->AddGlobal(kWasmI32, false, false, WasmInitExpr(i + 20000));
}
uint32_t global =
builder->AddGlobal(type, false, false, WasmInitExpr(expected));
for (int i = 0; i < padding; i++) { // pad global after
- builder->AddGlobal(kAstI32, false, false, WasmInitExpr(i + 30000));
+ builder->AddGlobal(kWasmI32, false, false, WasmInitExpr(i + 30000));
}
WasmFunctionBuilder* f1 = builder->AddFunction(&sig);
byte code[] = {WASM_GET_GLOBAL(global)};
- f1->EmitCode(code, sizeof(code));
+ EMIT_CODE_WITH_END(f1, code);
ExportAsMain(f1);
TestModule(&zone, builder, expected);
}
@@ -761,18 +817,18 @@ static void RunWasmModuleGlobalInitTest(LocalType type, CType expected) {
}
TEST(Run_WasmModule_Global_i32) {
- RunWasmModuleGlobalInitTest<int32_t>(kAstI32, -983489);
- RunWasmModuleGlobalInitTest<int32_t>(kAstI32, 11223344);
+ RunWasmModuleGlobalInitTest<int32_t>(kWasmI32, -983489);
+ RunWasmModuleGlobalInitTest<int32_t>(kWasmI32, 11223344);
}
TEST(Run_WasmModule_Global_f32) {
- RunWasmModuleGlobalInitTest<float>(kAstF32, -983.9f);
- RunWasmModuleGlobalInitTest<float>(kAstF32, 1122.99f);
+ RunWasmModuleGlobalInitTest<float>(kWasmF32, -983.9f);
+ RunWasmModuleGlobalInitTest<float>(kWasmF32, 1122.99f);
}
TEST(Run_WasmModule_Global_f64) {
- RunWasmModuleGlobalInitTest<double>(kAstF64, -833.9);
- RunWasmModuleGlobalInitTest<double>(kAstF64, 86374.25);
+ RunWasmModuleGlobalInitTest<double>(kWasmF64, -833.9);
+ RunWasmModuleGlobalInitTest<double>(kWasmF64, 86374.25);
}
TEST(InitDataAtTheUpperLimit) {
@@ -867,7 +923,7 @@ TEST(EmptyMemoryEmptyDataSegment) {
U32V_1(6), // section size
ENTRY_COUNT(1), // --
0, // linear memory index
- WASM_I32V_1(24), // destination offset
+ WASM_I32V_1(0), // destination offset
kExprEnd,
U32V_1(0), // source size
};
@@ -909,8 +965,8 @@ TEST(MemoryWithOOBEmptyDataSegment) {
testing::CompileInstantiateWasmModuleForTesting(isolate, &thrower, data,
data + arraysize(data),
ModuleOrigin::kWasmOrigin);
- // It should be possible to instantiate this module.
- CHECK(!thrower.error());
+ // It should not be possible to instantiate this module.
+ CHECK(thrower.error());
}
Cleanup();
}
diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-relocation.cc b/deps/v8/test/cctest/wasm/test-run-wasm-relocation.cc
index 614e9a4ba5..f34a1a323e 100644
--- a/deps/v8/test/cctest/wasm/test-run-wasm-relocation.cc
+++ b/deps/v8/test/cctest/wasm/test-run-wasm-relocation.cc
@@ -13,31 +13,29 @@
using namespace v8::internal;
using namespace v8::internal::compiler;
-#define FOREACH_TYPE(TEST_BODY) \
- TEST_BODY(int32_t, I32, WASM_I32_ADD) \
- TEST_BODY(int64_t, I64, WASM_I64_ADD) \
- TEST_BODY(float, F32, WASM_F32_ADD) \
- TEST_BODY(double, F64, WASM_F64_ADD)
+#define FOREACH_TYPE(TEST_BODY) \
+ TEST_BODY(int32_t, WASM_I32_ADD) \
+ TEST_BODY(int64_t, WASM_I64_ADD) \
+ TEST_BODY(float, WASM_F32_ADD) \
+ TEST_BODY(double, WASM_F64_ADD)
-#define LOAD_SET_GLOBAL_TEST_BODY(C_TYPE, MACHINE_TYPE, ADD) \
- TEST(WasmRelocateGlobal##MACHINE_TYPE) { \
- TestingModule module(kExecuteCompiled); \
- module.AddGlobal<C_TYPE>(kAst##MACHINE_TYPE); \
- module.AddGlobal<C_TYPE>(kAst##MACHINE_TYPE); \
+#define LOAD_SET_GLOBAL_TEST_BODY(C_TYPE, ADD) \
+ TEST(WasmRelocateGlobal_##C_TYPE) { \
+ WasmRunner<C_TYPE, C_TYPE> r(kExecuteCompiled); \
\
- WasmRunner<C_TYPE> r(&module, \
- WasmOpcodes::MachineTypeFor(kAst##MACHINE_TYPE)); \
+ r.module().AddGlobal<C_TYPE>(); \
+ r.module().AddGlobal<C_TYPE>(); \
\
/* global = global + p0 */ \
BUILD(r, WASM_SET_GLOBAL(1, ADD(WASM_GET_GLOBAL(0), WASM_GET_LOCAL(0))), \
WASM_GET_GLOBAL(0)); \
- CHECK_EQ(1u, module.instance->function_code.size()); \
+ CHECK_EQ(1, r.module().instance->function_code.size()); \
\
int filter = 1 << RelocInfo::WASM_GLOBAL_REFERENCE; \
\
- Handle<Code> code = module.instance->function_code[0]; \
+ Handle<Code> code = r.module().instance->function_code[0]; \
\
- Address old_start = module.instance->globals_start; \
+ Address old_start = r.module().instance->globals_start; \
Address new_start = old_start + 1; \
\
Address old_addresses[4]; \
diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-simd-lowering.cc b/deps/v8/test/cctest/wasm/test-run-wasm-simd-lowering.cc
index 69e770b9b8..706de8de35 100644
--- a/deps/v8/test/cctest/wasm/test-run-wasm-simd-lowering.cc
+++ b/deps/v8/test/cctest/wasm/test-run-wasm-simd-lowering.cc
@@ -15,82 +15,282 @@ using namespace v8::internal;
using namespace v8::internal::compiler;
using namespace v8::internal::wasm;
-WASM_EXEC_TEST(Simd_I32x4_Splat) {
+WASM_EXEC_COMPILED_TEST(Simd_I32x4_Splat) {
FLAG_wasm_simd_prototype = true;
- WasmRunner<int32_t> r(kExecuteCompiled, MachineType::Int32());
+ WasmRunner<int32_t> r(kExecuteCompiled);
BUILD(r,
WASM_SIMD_I32x4_EXTRACT_LANE(0, WASM_SIMD_I32x4_SPLAT(WASM_I32V(5))));
FOR_INT32_INPUTS(i) { CHECK_EQ(5, r.Call()); }
}
-WASM_EXEC_TEST(Simd_I32x4_Add) {
+WASM_EXEC_COMPILED_TEST(Simd_I32x4_Add) {
FLAG_wasm_simd_prototype = true;
- WasmRunner<int32_t> r(kExecuteCompiled, MachineType::Int32());
+ WasmRunner<int32_t> r(kExecuteCompiled);
BUILD(r, WASM_SIMD_I32x4_EXTRACT_LANE(
0, WASM_SIMD_I32x4_ADD(WASM_SIMD_I32x4_SPLAT(WASM_I32V(5)),
WASM_SIMD_I32x4_SPLAT(WASM_I32V(6)))));
FOR_INT32_INPUTS(i) { CHECK_EQ(11, r.Call()); }
}
-WASM_EXEC_TEST(Simd_F32x4_Splat) {
+WASM_EXEC_COMPILED_TEST(Simd_F32x4_Splat) {
FLAG_wasm_simd_prototype = true;
- WasmRunner<int32_t> r(kExecuteCompiled, MachineType::Int32());
+ WasmRunner<int32_t> r(kExecuteCompiled);
BUILD(r,
- WASM_IF_ELSE(WASM_F32_EQ(WASM_SIMD_F32x4_EXTRACT_LANE(
- 0, WASM_SIMD_F32x4_SPLAT(WASM_F32(9.5))),
- WASM_F32(9.5)),
- WASM_RETURN1(WASM_I32V(1)), WASM_RETURN1(WASM_I32V(0))));
+ WASM_IF_ELSE_I(WASM_F32_EQ(WASM_SIMD_F32x4_EXTRACT_LANE(
+ 0, WASM_SIMD_F32x4_SPLAT(WASM_F32(9.5))),
+ WASM_F32(9.5)),
+ WASM_I32V(1), WASM_I32V(0)));
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call()); }
}
-WASM_EXEC_TEST(Simd_I32x4_Extract_With_F32x4) {
+WASM_EXEC_COMPILED_TEST(Simd_I32x4_Extract_With_F32x4) {
FLAG_wasm_simd_prototype = true;
- WasmRunner<int32_t> r(kExecuteCompiled, MachineType::Int32());
- BUILD(r,
- WASM_IF_ELSE(WASM_I32_EQ(WASM_SIMD_I32x4_EXTRACT_LANE(
- 0, WASM_SIMD_F32x4_SPLAT(WASM_F32(30.5))),
- WASM_I32_REINTERPRET_F32(WASM_F32(30.5))),
- WASM_RETURN1(WASM_I32V(1)), WASM_RETURN1(WASM_I32V(0))));
+ WasmRunner<int32_t> r(kExecuteCompiled);
+ BUILD(r, WASM_IF_ELSE_I(
+ WASM_I32_EQ(WASM_SIMD_I32x4_EXTRACT_LANE(
+ 0, WASM_SIMD_F32x4_SPLAT(WASM_F32(30.5))),
+ WASM_I32_REINTERPRET_F32(WASM_F32(30.5))),
+ WASM_I32V(1), WASM_I32V(0)));
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call()); }
}
-WASM_EXEC_TEST(Simd_F32x4_Extract_With_I32x4) {
+WASM_EXEC_COMPILED_TEST(Simd_F32x4_Extract_With_I32x4) {
FLAG_wasm_simd_prototype = true;
- WasmRunner<int32_t> r(kExecuteCompiled, MachineType::Int32());
+ WasmRunner<int32_t> r(kExecuteCompiled);
BUILD(r,
- WASM_IF_ELSE(WASM_F32_EQ(WASM_SIMD_F32x4_EXTRACT_LANE(
- 0, WASM_SIMD_I32x4_SPLAT(WASM_I32V(15))),
- WASM_F32_REINTERPRET_I32(WASM_I32V(15))),
- WASM_RETURN1(WASM_I32V(1)), WASM_RETURN1(WASM_I32V(0))));
+ WASM_IF_ELSE_I(WASM_F32_EQ(WASM_SIMD_F32x4_EXTRACT_LANE(
+ 0, WASM_SIMD_I32x4_SPLAT(WASM_I32V(15))),
+ WASM_F32_REINTERPRET_I32(WASM_I32V(15))),
+ WASM_I32V(1), WASM_I32V(0)));
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call()); }
}
-WASM_EXEC_TEST(Simd_F32x4_Add_With_I32x4) {
+WASM_EXEC_COMPILED_TEST(Simd_F32x4_Add_With_I32x4) {
FLAG_wasm_simd_prototype = true;
- WasmRunner<int32_t> r(kExecuteCompiled, MachineType::Int32());
+ WasmRunner<int32_t> r(kExecuteCompiled);
BUILD(r,
- WASM_IF_ELSE(
+ WASM_IF_ELSE_I(
WASM_F32_EQ(WASM_SIMD_F32x4_EXTRACT_LANE(
0, WASM_SIMD_F32x4_ADD(
WASM_SIMD_I32x4_SPLAT(WASM_I32V(32)),
WASM_SIMD_I32x4_SPLAT(WASM_I32V(19)))),
WASM_F32_ADD(WASM_F32_REINTERPRET_I32(WASM_I32V(32)),
WASM_F32_REINTERPRET_I32(WASM_I32V(19)))),
- WASM_RETURN1(WASM_I32V(1)), WASM_RETURN1(WASM_I32V(0))));
+ WASM_I32V(1), WASM_I32V(0)));
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call()); }
}
-WASM_EXEC_TEST(Simd_I32x4_Add_With_F32x4) {
+WASM_EXEC_COMPILED_TEST(Simd_I32x4_Add_With_F32x4) {
FLAG_wasm_simd_prototype = true;
- WasmRunner<int32_t> r(kExecuteCompiled, MachineType::Int32());
+ WasmRunner<int32_t> r(kExecuteCompiled);
BUILD(r,
- WASM_IF_ELSE(
+ WASM_IF_ELSE_I(
WASM_I32_EQ(WASM_SIMD_I32x4_EXTRACT_LANE(
0, WASM_SIMD_I32x4_ADD(
WASM_SIMD_F32x4_SPLAT(WASM_F32(21.25)),
WASM_SIMD_F32x4_SPLAT(WASM_F32(31.5)))),
WASM_I32_ADD(WASM_I32_REINTERPRET_F32(WASM_F32(21.25)),
WASM_I32_REINTERPRET_F32(WASM_F32(31.5)))),
- WASM_RETURN1(WASM_I32V(1)), WASM_RETURN1(WASM_I32V(0))));
+ WASM_I32V(1), WASM_I32V(0)));
+ FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call()); }
+}
+
+WASM_EXEC_COMPILED_TEST(Simd_I32x4_Local) {
+ FLAG_wasm_simd_prototype = true;
+ WasmRunner<int32_t> r(kExecuteCompiled);
+ r.AllocateLocal(kWasmS128);
+ BUILD(r, WASM_SET_LOCAL(0, WASM_SIMD_I32x4_SPLAT(WASM_I32V(31))),
+
+ WASM_SIMD_I32x4_EXTRACT_LANE(0, WASM_GET_LOCAL(0)));
+ FOR_INT32_INPUTS(i) { CHECK_EQ(31, r.Call()); }
+}
+
+WASM_EXEC_COMPILED_TEST(Simd_I32x4_Replace_Lane) {
+ FLAG_wasm_simd_prototype = true;
+ WasmRunner<int32_t> r(kExecuteCompiled);
+ r.AllocateLocal(kWasmS128);
+ BUILD(r, WASM_SET_LOCAL(0, WASM_SIMD_I32x4_SPLAT(WASM_I32V(31))),
+ WASM_SET_LOCAL(0, WASM_SIMD_I32x4_REPLACE_LANE(2, WASM_GET_LOCAL(0),
+ WASM_I32V(53))),
+ WASM_SIMD_I32x4_EXTRACT_LANE(2, WASM_GET_LOCAL(0)));
+ FOR_INT32_INPUTS(i) { CHECK_EQ(53, r.Call()); }
+}
+
+WASM_EXEC_COMPILED_TEST(Simd_F32x4_Replace_Lane) {
+ FLAG_wasm_simd_prototype = true;
+ WasmRunner<int32_t> r(kExecuteCompiled);
+ r.AllocateLocal(kWasmF32);
+ r.AllocateLocal(kWasmS128);
+ BUILD(r, WASM_SET_LOCAL(1, WASM_SIMD_F32x4_SPLAT(WASM_F32(23.5))),
+ WASM_SET_LOCAL(1, WASM_SIMD_F32x4_REPLACE_LANE(3, WASM_GET_LOCAL(1),
+ WASM_F32(65.25))),
+ WASM_SET_LOCAL(0, WASM_SIMD_F32x4_EXTRACT_LANE(3, WASM_GET_LOCAL(1))),
+ WASM_IF(WASM_F32_EQ(WASM_GET_LOCAL(0), WASM_F32(65.25)),
+ WASM_RETURN1(WASM_I32V(1))),
+ WASM_I32V(0));
+ FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call()); }
+}
+
+WASM_EXEC_COMPILED_TEST(Simd_I32x4_Splat_From_Extract) {
+ FLAG_wasm_simd_prototype = true;
+ WasmRunner<int32_t> r(kExecuteCompiled);
+ r.AllocateLocal(kWasmI32);
+ r.AllocateLocal(kWasmS128);
+ BUILD(r, WASM_SET_LOCAL(0, WASM_SIMD_I32x4_EXTRACT_LANE(
+ 0, WASM_SIMD_I32x4_SPLAT(WASM_I32V(76)))),
+ WASM_SET_LOCAL(1, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(0))),
+ WASM_SIMD_I32x4_EXTRACT_LANE(1, WASM_GET_LOCAL(1)));
+ FOR_INT32_INPUTS(i) { CHECK_EQ(76, r.Call()); }
+}
+
+WASM_EXEC_COMPILED_TEST(Simd_I32x4_Get_Global) {
+ FLAG_wasm_simd_prototype = true;
+ WasmRunner<int32_t, int32_t> r(kExecuteCompiled);
+ int32_t* global = r.module().AddGlobal<int32_t>(kWasmS128);
+ *(global) = 0;
+ *(global + 1) = 1;
+ *(global + 2) = 2;
+ *(global + 3) = 3;
+ r.AllocateLocal(kWasmI32);
+ BUILD(
+ r, WASM_SET_LOCAL(1, WASM_I32V(1)),
+ WASM_IF(WASM_I32_NE(WASM_I32V(0),
+ WASM_SIMD_I32x4_EXTRACT_LANE(0, WASM_GET_GLOBAL(0))),
+ WASM_SET_LOCAL(1, WASM_I32V(0))),
+ WASM_IF(WASM_I32_NE(WASM_I32V(1),
+ WASM_SIMD_I32x4_EXTRACT_LANE(1, WASM_GET_GLOBAL(0))),
+ WASM_SET_LOCAL(1, WASM_I32V(0))),
+ WASM_IF(WASM_I32_NE(WASM_I32V(2),
+ WASM_SIMD_I32x4_EXTRACT_LANE(2, WASM_GET_GLOBAL(0))),
+ WASM_SET_LOCAL(1, WASM_I32V(0))),
+ WASM_IF(WASM_I32_NE(WASM_I32V(3),
+ WASM_SIMD_I32x4_EXTRACT_LANE(3, WASM_GET_GLOBAL(0))),
+ WASM_SET_LOCAL(1, WASM_I32V(0))),
+ WASM_GET_LOCAL(1));
+ FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call(0)); }
+}
+
+WASM_EXEC_COMPILED_TEST(Simd_I32x4_Set_Global) {
+ FLAG_wasm_simd_prototype = true;
+ WasmRunner<int32_t, int32_t> r(kExecuteCompiled);
+ int32_t* global = r.module().AddGlobal<int32_t>(kWasmS128);
+ BUILD(r, WASM_SET_GLOBAL(0, WASM_SIMD_I32x4_SPLAT(WASM_I32V(23))),
+ WASM_SET_GLOBAL(0, WASM_SIMD_I32x4_REPLACE_LANE(1, WASM_GET_GLOBAL(0),
+ WASM_I32V(34))),
+ WASM_SET_GLOBAL(0, WASM_SIMD_I32x4_REPLACE_LANE(2, WASM_GET_GLOBAL(0),
+ WASM_I32V(45))),
+ WASM_SET_GLOBAL(0, WASM_SIMD_I32x4_REPLACE_LANE(3, WASM_GET_GLOBAL(0),
+ WASM_I32V(56))),
+ WASM_I32V(1));
+ FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call(0)); }
+ CHECK_EQ(*global, 23);
+ CHECK_EQ(*(global + 1), 34);
+ CHECK_EQ(*(global + 2), 45);
+ CHECK_EQ(*(global + 3), 56);
+}
+
+WASM_EXEC_COMPILED_TEST(Simd_F32x4_Get_Global) {
+ FLAG_wasm_simd_prototype = true;
+ WasmRunner<int32_t, int32_t> r(kExecuteCompiled);
+ float* global = r.module().AddGlobal<float>(kWasmS128);
+ *(global) = 0.0;
+ *(global + 1) = 1.5;
+ *(global + 2) = 2.25;
+ *(global + 3) = 3.5;
+ r.AllocateLocal(kWasmI32);
+ BUILD(
+ r, WASM_SET_LOCAL(1, WASM_I32V(1)),
+ WASM_IF(WASM_F32_NE(WASM_F32(0.0),
+ WASM_SIMD_F32x4_EXTRACT_LANE(0, WASM_GET_GLOBAL(0))),
+ WASM_SET_LOCAL(1, WASM_I32V(0))),
+ WASM_IF(WASM_F32_NE(WASM_F32(1.5),
+ WASM_SIMD_F32x4_EXTRACT_LANE(1, WASM_GET_GLOBAL(0))),
+ WASM_SET_LOCAL(1, WASM_I32V(0))),
+ WASM_IF(WASM_F32_NE(WASM_F32(2.25),
+ WASM_SIMD_F32x4_EXTRACT_LANE(2, WASM_GET_GLOBAL(0))),
+ WASM_SET_LOCAL(1, WASM_I32V(0))),
+ WASM_IF(WASM_F32_NE(WASM_F32(3.5),
+ WASM_SIMD_F32x4_EXTRACT_LANE(3, WASM_GET_GLOBAL(0))),
+ WASM_SET_LOCAL(1, WASM_I32V(0))),
+ WASM_GET_LOCAL(1));
+ FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call(0)); }
+}
+
+WASM_EXEC_COMPILED_TEST(Simd_F32x4_Set_Global) {
+ FLAG_wasm_simd_prototype = true;
+ WasmRunner<int32_t, int32_t> r(kExecuteCompiled);
+ float* global = r.module().AddGlobal<float>(kWasmS128);
+ BUILD(r, WASM_SET_GLOBAL(0, WASM_SIMD_F32x4_SPLAT(WASM_F32(13.5))),
+ WASM_SET_GLOBAL(0, WASM_SIMD_F32x4_REPLACE_LANE(1, WASM_GET_GLOBAL(0),
+ WASM_F32(45.5))),
+ WASM_SET_GLOBAL(0, WASM_SIMD_F32x4_REPLACE_LANE(2, WASM_GET_GLOBAL(0),
+ WASM_F32(32.25))),
+ WASM_SET_GLOBAL(0, WASM_SIMD_F32x4_REPLACE_LANE(3, WASM_GET_GLOBAL(0),
+ WASM_F32(65.0))),
+ WASM_I32V(1));
+ FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call(0)); }
+ CHECK_EQ(*global, 13.5);
+ CHECK_EQ(*(global + 1), 45.5);
+ CHECK_EQ(*(global + 2), 32.25);
+ CHECK_EQ(*(global + 3), 65.0);
+}
+
+WASM_EXEC_COMPILED_TEST(Simd_I32x4_For) {
+ FLAG_wasm_simd_prototype = true;
+ WasmRunner<int32_t> r(kExecuteCompiled);
+ r.AllocateLocal(kWasmI32);
+ r.AllocateLocal(kWasmS128);
+ BUILD(r,
+
+ WASM_SET_LOCAL(1, WASM_SIMD_I32x4_SPLAT(WASM_I32V(31))),
+ WASM_SET_LOCAL(1, WASM_SIMD_I32x4_REPLACE_LANE(1, WASM_GET_LOCAL(1),
+ WASM_I32V(53))),
+ WASM_SET_LOCAL(1, WASM_SIMD_I32x4_REPLACE_LANE(2, WASM_GET_LOCAL(1),
+ WASM_I32V(23))),
+ WASM_SET_LOCAL(0, WASM_I32V(0)),
+ WASM_LOOP(
+ WASM_SET_LOCAL(
+ 1, WASM_SIMD_I32x4_ADD(WASM_GET_LOCAL(1),
+ WASM_SIMD_I32x4_SPLAT(WASM_I32V(1)))),
+ WASM_IF(WASM_I32_NE(WASM_INC_LOCAL(0), WASM_I32V(5)), WASM_BR(1))),
+ WASM_SET_LOCAL(0, WASM_I32V(1)),
+ WASM_IF(WASM_I32_NE(WASM_SIMD_I32x4_EXTRACT_LANE(0, WASM_GET_LOCAL(1)),
+ WASM_I32V(36)),
+ WASM_SET_LOCAL(0, WASM_I32V(0))),
+ WASM_IF(WASM_I32_NE(WASM_SIMD_I32x4_EXTRACT_LANE(1, WASM_GET_LOCAL(1)),
+ WASM_I32V(58)),
+ WASM_SET_LOCAL(0, WASM_I32V(0))),
+ WASM_IF(WASM_I32_NE(WASM_SIMD_I32x4_EXTRACT_LANE(2, WASM_GET_LOCAL(1)),
+ WASM_I32V(28)),
+ WASM_SET_LOCAL(0, WASM_I32V(0))),
+ WASM_IF(WASM_I32_NE(WASM_SIMD_I32x4_EXTRACT_LANE(3, WASM_GET_LOCAL(1)),
+ WASM_I32V(36)),
+ WASM_SET_LOCAL(0, WASM_I32V(0))),
+ WASM_GET_LOCAL(0));
+ FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call()); }
+}
+
+WASM_EXEC_COMPILED_TEST(Simd_F32x4_For) {
+ FLAG_wasm_simd_prototype = true;
+ WasmRunner<int32_t> r(kExecuteCompiled);
+ r.AllocateLocal(kWasmI32);
+ r.AllocateLocal(kWasmS128);
+ BUILD(r, WASM_SET_LOCAL(1, WASM_SIMD_F32x4_SPLAT(WASM_F32(21.25))),
+ WASM_SET_LOCAL(1, WASM_SIMD_F32x4_REPLACE_LANE(3, WASM_GET_LOCAL(1),
+ WASM_F32(19.5))),
+ WASM_SET_LOCAL(0, WASM_I32V(0)),
+ WASM_LOOP(
+ WASM_SET_LOCAL(
+ 1, WASM_SIMD_F32x4_ADD(WASM_GET_LOCAL(1),
+ WASM_SIMD_F32x4_SPLAT(WASM_F32(2.0)))),
+ WASM_IF(WASM_I32_NE(WASM_INC_LOCAL(0), WASM_I32V(3)), WASM_BR(1))),
+ WASM_SET_LOCAL(0, WASM_I32V(1)),
+ WASM_IF(WASM_F32_NE(WASM_SIMD_F32x4_EXTRACT_LANE(0, WASM_GET_LOCAL(1)),
+ WASM_F32(27.25)),
+ WASM_SET_LOCAL(0, WASM_I32V(0))),
+ WASM_IF(WASM_F32_NE(WASM_SIMD_F32x4_EXTRACT_LANE(3, WASM_GET_LOCAL(1)),
+ WASM_F32(25.5)),
+ WASM_SET_LOCAL(0, WASM_I32V(0))),
+ WASM_GET_LOCAL(0));
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call()); }
}
diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-simd.cc b/deps/v8/test/cctest/wasm/test-run-wasm-simd.cc
index 76eac5e793..9764545d45 100644
--- a/deps/v8/test/cctest/wasm/test-run-wasm-simd.cc
+++ b/deps/v8/test/cctest/wasm/test-run-wasm-simd.cc
@@ -13,7 +13,259 @@ using namespace v8::internal;
using namespace v8::internal::compiler;
using namespace v8::internal::wasm;
-WASM_EXEC_TEST(Splat) {
+namespace {
+
+typedef float (*FloatUnOp)(float);
+typedef float (*FloatBinOp)(float, float);
+typedef int32_t (*FloatCompareOp)(float, float);
+typedef int32_t (*Int32BinOp)(int32_t, int32_t);
+
+template <typename T>
+T Negate(T a) {
+ return -a;
+}
+
+template <typename T>
+T Add(T a, T b) {
+ return a + b;
+}
+
+template <typename T>
+T Sub(T a, T b) {
+ return a - b;
+}
+
+template <typename T>
+int32_t Equal(T a, T b) {
+ return a == b ? 0xFFFFFFFF : 0;
+}
+
+template <typename T>
+int32_t NotEqual(T a, T b) {
+ return a != b ? 0xFFFFFFFF : 0;
+}
+
+#if V8_TARGET_ARCH_ARM
+int32_t Equal(float a, float b) { return a == b ? 0xFFFFFFFF : 0; }
+
+int32_t NotEqual(float a, float b) { return a != b ? 0xFFFFFFFF : 0; }
+#endif // V8_TARGET_ARCH_ARM
+
+} // namespace
+
+// TODO(gdeepti): These are tests using sample values to verify functional
+// correctness of opcodes, add more tests for a range of values and macroize
+// tests.
+
+// TODO(bbudge) Figure out how to compare floats in Wasm code that can handle
+// NaNs. For now, our tests avoid using NaNs.
+#define WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lane_value, lane_index) \
+ WASM_IF(WASM_##LANE_TYPE##_NE(WASM_GET_LOCAL(lane_value), \
+ WASM_SIMD_##TYPE##_EXTRACT_LANE( \
+ lane_index, WASM_GET_LOCAL(value))), \
+ WASM_RETURN1(WASM_ZERO))
+
+#define WASM_SIMD_CHECK4(TYPE, value, LANE_TYPE, lv0, lv1, lv2, lv3) \
+ WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv0, 0) \
+ , WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv1, 1), \
+ WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv2, 2), \
+ WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lv3, 3)
+
+#define WASM_SIMD_CHECK_SPLAT4(TYPE, value, LANE_TYPE, lv) \
+ WASM_SIMD_CHECK4(TYPE, value, LANE_TYPE, lv, lv, lv, lv)
+
+#define WASM_SIMD_CHECK_F32_LANE(TYPE, value, lane_value, lane_index) \
+ WASM_IF( \
+ WASM_I32_NE(WASM_I32_REINTERPRET_F32(WASM_GET_LOCAL(lane_value)), \
+ WASM_I32_REINTERPRET_F32(WASM_SIMD_##TYPE##_EXTRACT_LANE( \
+ lane_index, WASM_GET_LOCAL(value)))), \
+ WASM_RETURN1(WASM_ZERO))
+
+#define WASM_SIMD_CHECK4_F32(TYPE, value, lv0, lv1, lv2, lv3) \
+ WASM_SIMD_CHECK_F32_LANE(TYPE, value, lv0, 0) \
+ , WASM_SIMD_CHECK_F32_LANE(TYPE, value, lv1, 1), \
+ WASM_SIMD_CHECK_F32_LANE(TYPE, value, lv2, 2), \
+ WASM_SIMD_CHECK_F32_LANE(TYPE, value, lv3, 3)
+
+#define WASM_SIMD_CHECK_SPLAT4_F32(TYPE, value, lv) \
+ WASM_SIMD_CHECK4_F32(TYPE, value, lv, lv, lv, lv)
+
+#if V8_TARGET_ARCH_ARM
+WASM_EXEC_TEST(F32x4Splat) {
+ FLAG_wasm_simd_prototype = true;
+
+ WasmRunner<int32_t, float> r(kExecuteCompiled);
+ byte lane_val = 0;
+ byte simd = r.AllocateLocal(kWasmS128);
+ BUILD(r,
+ WASM_SET_LOCAL(simd, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(lane_val))),
+ WASM_SIMD_CHECK_SPLAT4_F32(F32x4, simd, lane_val), WASM_ONE);
+
+ FOR_FLOAT32_INPUTS(i) { CHECK_EQ(1, r.Call(*i)); }
+}
+
+WASM_EXEC_TEST(F32x4ReplaceLane) {
+ FLAG_wasm_simd_prototype = true;
+ WasmRunner<int32_t, float, float> r(kExecuteCompiled);
+ byte old_val = 0;
+ byte new_val = 1;
+ byte simd = r.AllocateLocal(kWasmS128);
+ BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(old_val))),
+ WASM_SET_LOCAL(simd,
+ WASM_SIMD_F32x4_REPLACE_LANE(0, WASM_GET_LOCAL(simd),
+ WASM_GET_LOCAL(new_val))),
+ WASM_SIMD_CHECK4(F32x4, simd, F32, new_val, old_val, old_val, old_val),
+ WASM_SET_LOCAL(simd,
+ WASM_SIMD_F32x4_REPLACE_LANE(1, WASM_GET_LOCAL(simd),
+ WASM_GET_LOCAL(new_val))),
+ WASM_SIMD_CHECK4(F32x4, simd, F32, new_val, new_val, old_val, old_val),
+ WASM_SET_LOCAL(simd,
+ WASM_SIMD_F32x4_REPLACE_LANE(2, WASM_GET_LOCAL(simd),
+ WASM_GET_LOCAL(new_val))),
+ WASM_SIMD_CHECK4(F32x4, simd, F32, new_val, new_val, new_val, old_val),
+ WASM_SET_LOCAL(simd,
+ WASM_SIMD_F32x4_REPLACE_LANE(3, WASM_GET_LOCAL(simd),
+ WASM_GET_LOCAL(new_val))),
+ WASM_SIMD_CHECK_SPLAT4(F32x4, simd, F32, new_val), WASM_ONE);
+
+ CHECK_EQ(1, r.Call(3.14159, -1.5));
+}
+
+// Tests both signed and unsigned conversion.
+WASM_EXEC_TEST(F32x4FromInt32x4) {
+ FLAG_wasm_simd_prototype = true;
+ WasmRunner<int32_t, int32_t, float, float> r(kExecuteCompiled);
+ byte a = 0;
+ byte expected_signed = 1;
+ byte expected_unsigned = 2;
+ byte simd0 = r.AllocateLocal(kWasmS128);
+ byte simd1 = r.AllocateLocal(kWasmS128);
+ byte simd2 = r.AllocateLocal(kWasmS128);
+ BUILD(
+ r, WASM_SET_LOCAL(simd0, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(a))),
+ WASM_SET_LOCAL(simd1, WASM_SIMD_F32x4_FROM_I32x4(WASM_GET_LOCAL(simd0))),
+ WASM_SIMD_CHECK_SPLAT4_F32(F32x4, simd1, expected_signed),
+ WASM_SET_LOCAL(simd2, WASM_SIMD_F32x4_FROM_U32x4(WASM_GET_LOCAL(simd0))),
+ WASM_SIMD_CHECK_SPLAT4_F32(F32x4, simd2, expected_unsigned), WASM_ONE);
+
+ FOR_INT32_INPUTS(i) {
+ CHECK_EQ(1, r.Call(*i, static_cast<float>(*i),
+ static_cast<float>(static_cast<uint32_t>(*i))));
+ }
+}
+
+WASM_EXEC_TEST(S32x4Select) {
+ FLAG_wasm_simd_prototype = true;
+ WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled);
+ byte val1 = 0;
+ byte val2 = 1;
+ byte mask = r.AllocateLocal(kWasmS128);
+ byte src1 = r.AllocateLocal(kWasmS128);
+ byte src2 = r.AllocateLocal(kWasmS128);
+ BUILD(r,
+
+ WASM_SET_LOCAL(mask, WASM_SIMD_I32x4_SPLAT(WASM_ZERO)),
+ WASM_SET_LOCAL(src1, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(val1))),
+ WASM_SET_LOCAL(src2, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(val2))),
+ WASM_SET_LOCAL(mask, WASM_SIMD_I32x4_REPLACE_LANE(
+ 1, WASM_GET_LOCAL(mask), WASM_I32V(-1))),
+ WASM_SET_LOCAL(mask, WASM_SIMD_I32x4_REPLACE_LANE(
+ 2, WASM_GET_LOCAL(mask), WASM_I32V(-1))),
+ WASM_SET_LOCAL(mask, WASM_SIMD_S32x4_SELECT(WASM_GET_LOCAL(mask),
+ WASM_GET_LOCAL(src1),
+ WASM_GET_LOCAL(src2))),
+ WASM_SIMD_CHECK_LANE(I32x4, mask, I32, val2, 0),
+ WASM_SIMD_CHECK_LANE(I32x4, mask, I32, val1, 1),
+ WASM_SIMD_CHECK_LANE(I32x4, mask, I32, val1, 2),
+ WASM_SIMD_CHECK_LANE(I32x4, mask, I32, val2, 3), WASM_ONE);
+
+ CHECK_EQ(1, r.Call(0x1234, 0x5678));
+}
+
+void RunF32x4UnOpTest(WasmOpcode simd_op, FloatUnOp expected_op) {
+ FLAG_wasm_simd_prototype = true;
+ WasmRunner<int32_t, float, float> r(kExecuteCompiled);
+ byte a = 0;
+ byte expected = 1;
+ byte simd = r.AllocateLocal(kWasmS128);
+ BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(a))),
+ WASM_SET_LOCAL(simd,
+ WASM_SIMD_UNOP(simd_op & 0xffu, WASM_GET_LOCAL(simd))),
+ WASM_SIMD_CHECK_SPLAT4_F32(F32x4, simd, expected), WASM_ONE);
+
+ FOR_FLOAT32_INPUTS(i) {
+ if (std::isnan(*i)) continue;
+ CHECK_EQ(1, r.Call(*i, expected_op(*i)));
+ }
+}
+
+WASM_EXEC_TEST(F32x4Abs) { RunF32x4UnOpTest(kExprF32x4Abs, std::abs); }
+WASM_EXEC_TEST(F32x4Neg) { RunF32x4UnOpTest(kExprF32x4Neg, Negate); }
+
+void RunF32x4BinOpTest(WasmOpcode simd_op, FloatBinOp expected_op) {
+ FLAG_wasm_simd_prototype = true;
+ WasmRunner<int32_t, float, float, float> r(kExecuteCompiled);
+ byte a = 0;
+ byte b = 1;
+ byte expected = 2;
+ byte simd0 = r.AllocateLocal(kWasmS128);
+ byte simd1 = r.AllocateLocal(kWasmS128);
+ BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(a))),
+ WASM_SET_LOCAL(simd1, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(b))),
+ WASM_SET_LOCAL(simd1,
+ WASM_SIMD_BINOP(simd_op & 0xffu, WASM_GET_LOCAL(simd0),
+ WASM_GET_LOCAL(simd1))),
+ WASM_SIMD_CHECK_SPLAT4_F32(F32x4, simd1, expected), WASM_ONE);
+
+ FOR_FLOAT32_INPUTS(i) {
+ if (std::isnan(*i)) continue;
+ FOR_FLOAT32_INPUTS(j) {
+ if (std::isnan(*j)) continue;
+ float expected = expected_op(*i, *j);
+ // SIMD on some platforms may handle denormalized numbers differently.
+ // TODO(bbudge) On platforms that flush denorms to zero, test with
+ // expected == 0.
+ if (std::fpclassify(expected) == FP_SUBNORMAL) continue;
+ CHECK_EQ(1, r.Call(*i, *j, expected));
+ }
+ }
+}
+
+WASM_EXEC_TEST(F32x4Add) { RunF32x4BinOpTest(kExprF32x4Add, Add); }
+WASM_EXEC_TEST(F32x4Sub) { RunF32x4BinOpTest(kExprF32x4Sub, Sub); }
+
+void RunF32x4CompareOpTest(WasmOpcode simd_op, FloatCompareOp expected_op) {
+ FLAG_wasm_simd_prototype = true;
+ WasmRunner<int32_t, float, float, int32_t> r(kExecuteCompiled);
+ byte a = 0;
+ byte b = 1;
+ byte expected = 2;
+ byte simd0 = r.AllocateLocal(kWasmS128);
+ byte simd1 = r.AllocateLocal(kWasmS128);
+ BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(a))),
+ WASM_SET_LOCAL(simd1, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(b))),
+ WASM_SET_LOCAL(simd1,
+ WASM_SIMD_BINOP(simd_op & 0xffu, WASM_GET_LOCAL(simd0),
+ WASM_GET_LOCAL(simd1))),
+ WASM_SIMD_CHECK_SPLAT4(I32x4, simd1, I32, expected), WASM_ONE);
+
+ FOR_FLOAT32_INPUTS(i) {
+ if (std::isnan(*i)) continue;
+ FOR_FLOAT32_INPUTS(j) {
+ if (std::isnan(*j)) continue;
+ // SIMD on some platforms may handle denormalized numbers differently.
+ // Check for number pairs that are very close together.
+ if (std::fpclassify(*i - *j) == FP_SUBNORMAL) continue;
+ CHECK_EQ(1, r.Call(*i, *j, expected_op(*i, *j)));
+ }
+ }
+}
+
+WASM_EXEC_TEST(F32x4Equal) { RunF32x4CompareOpTest(kExprF32x4Eq, Equal); }
+WASM_EXEC_TEST(F32x4NotEqual) { RunF32x4CompareOpTest(kExprF32x4Ne, NotEqual); }
+#endif // V8_TARGET_ARCH_ARM
+
+WASM_EXEC_TEST(I32x4Splat) {
FLAG_wasm_simd_prototype = true;
// Store SIMD value in a local variable, use extract lane to check lane values
@@ -26,24 +278,136 @@ WASM_EXEC_TEST(Splat) {
// return 0
//
// return 1
- WasmRunner<int32_t> r(kExecuteCompiled, MachineType::Int32());
- r.AllocateLocal(kAstS128);
+ WasmRunner<int32_t, int32_t> r(kExecuteCompiled);
+ byte lane_val = 0;
+ byte simd = r.AllocateLocal(kWasmS128);
BUILD(r,
- WASM_BLOCK(
- WASM_SET_LOCAL(1, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(0))),
- WASM_IF(WASM_I32_NE(WASM_GET_LOCAL(0), WASM_SIMD_I32x4_EXTRACT_LANE(
- 0, WASM_GET_LOCAL(1))),
- WASM_RETURN1(WASM_ZERO)),
- WASM_IF(WASM_I32_NE(WASM_GET_LOCAL(0), WASM_SIMD_I32x4_EXTRACT_LANE(
- 1, WASM_GET_LOCAL(1))),
- WASM_RETURN1(WASM_ZERO)),
- WASM_IF(WASM_I32_NE(WASM_GET_LOCAL(0), WASM_SIMD_I32x4_EXTRACT_LANE(
- 2, WASM_GET_LOCAL(1))),
- WASM_RETURN1(WASM_ZERO)),
- WASM_IF(WASM_I32_NE(WASM_GET_LOCAL(0), WASM_SIMD_I32x4_EXTRACT_LANE(
- 3, WASM_GET_LOCAL(1))),
- WASM_RETURN1(WASM_ZERO)),
- WASM_RETURN1(WASM_ONE)));
+ WASM_SET_LOCAL(simd, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(lane_val))),
+ WASM_SIMD_CHECK_SPLAT4(I32x4, simd, I32, lane_val), WASM_ONE);
FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call(*i)); }
}
+
+WASM_EXEC_TEST(I32x4ReplaceLane) {
+ FLAG_wasm_simd_prototype = true;
+ WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled);
+ byte old_val = 0;
+ byte new_val = 1;
+ byte simd = r.AllocateLocal(kWasmS128);
+ BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(old_val))),
+ WASM_SET_LOCAL(simd,
+ WASM_SIMD_I32x4_REPLACE_LANE(0, WASM_GET_LOCAL(simd),
+ WASM_GET_LOCAL(new_val))),
+ WASM_SIMD_CHECK4(I32x4, simd, I32, new_val, old_val, old_val, old_val),
+ WASM_SET_LOCAL(simd,
+ WASM_SIMD_I32x4_REPLACE_LANE(1, WASM_GET_LOCAL(simd),
+ WASM_GET_LOCAL(new_val))),
+ WASM_SIMD_CHECK4(I32x4, simd, I32, new_val, new_val, old_val, old_val),
+ WASM_SET_LOCAL(simd,
+ WASM_SIMD_I32x4_REPLACE_LANE(2, WASM_GET_LOCAL(simd),
+ WASM_GET_LOCAL(new_val))),
+ WASM_SIMD_CHECK4(I32x4, simd, I32, new_val, new_val, new_val, old_val),
+ WASM_SET_LOCAL(simd,
+ WASM_SIMD_I32x4_REPLACE_LANE(3, WASM_GET_LOCAL(simd),
+ WASM_GET_LOCAL(new_val))),
+ WASM_SIMD_CHECK_SPLAT4(I32x4, simd, I32, new_val), WASM_ONE);
+
+ CHECK_EQ(1, r.Call(1, 2));
+}
+
+#if V8_TARGET_ARCH_ARM
+
+// Determines if conversion from float to int will be valid.
+bool CanRoundToZeroAndConvert(double val, bool unsigned_integer) {
+ const double max_uint = static_cast<double>(0xffffffffu);
+ const double max_int = static_cast<double>(kMaxInt);
+ const double min_int = static_cast<double>(kMinInt);
+
+ // Check for NaN.
+ if (val != val) {
+ return false;
+ }
+
+ // Round to zero and check for overflow. This code works because 32 bit
+ // integers can be exactly represented by ieee-754 64bit floating-point
+ // values.
+ return unsigned_integer ? (val < (max_uint + 1.0)) && (val > -1)
+ : (val < (max_int + 1.0)) && (val > (min_int - 1.0));
+}
+
+int ConvertInvalidValue(double val, bool unsigned_integer) {
+ if (val != val) {
+ return 0;
+ } else {
+ if (unsigned_integer) {
+ return (val < 0) ? 0 : 0xffffffffu;
+ } else {
+ return (val < 0) ? kMinInt : kMaxInt;
+ }
+ }
+}
+
+int32_t ConvertToInt(double val, bool unsigned_integer) {
+ int32_t result =
+ unsigned_integer ? static_cast<uint32_t>(val) : static_cast<int32_t>(val);
+
+ if (!CanRoundToZeroAndConvert(val, unsigned_integer)) {
+ result = ConvertInvalidValue(val, unsigned_integer);
+ }
+ return result;
+}
+
+// Tests both signed and unsigned conversion.
+WASM_EXEC_TEST(I32x4FromFloat32x4) {
+ FLAG_wasm_simd_prototype = true;
+ WasmRunner<int32_t, float, int32_t, int32_t> r(kExecuteCompiled);
+ byte a = 0;
+ byte expected_signed = 1;
+ byte expected_unsigned = 2;
+ byte simd0 = r.AllocateLocal(kWasmS128);
+ byte simd1 = r.AllocateLocal(kWasmS128);
+ byte simd2 = r.AllocateLocal(kWasmS128);
+ BUILD(
+ r, WASM_SET_LOCAL(simd0, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(a))),
+ WASM_SET_LOCAL(simd1, WASM_SIMD_I32x4_FROM_F32x4(WASM_GET_LOCAL(simd0))),
+ WASM_SIMD_CHECK_SPLAT4(I32x4, simd1, I32, expected_signed),
+ WASM_SET_LOCAL(simd2, WASM_SIMD_U32x4_FROM_F32x4(WASM_GET_LOCAL(simd0))),
+ WASM_SIMD_CHECK_SPLAT4(I32x4, simd2, I32, expected_unsigned), WASM_ONE);
+
+ FOR_FLOAT32_INPUTS(i) {
+ int32_t signed_value = ConvertToInt(*i, false);
+ int32_t unsigned_value = ConvertToInt(*i, true);
+ CHECK_EQ(1, r.Call(*i, signed_value, unsigned_value));
+ }
+}
+#endif // V8_TARGET_ARCH_ARM
+
+void RunI32x4BinOpTest(WasmOpcode simd_op, Int32BinOp expected_op) {
+ FLAG_wasm_simd_prototype = true;
+ WasmRunner<int32_t, int32_t, int32_t, int32_t> r(kExecuteCompiled);
+ byte a = 0;
+ byte b = 1;
+ byte expected = 2;
+ byte simd0 = r.AllocateLocal(kWasmS128);
+ byte simd1 = r.AllocateLocal(kWasmS128);
+ BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(a))),
+ WASM_SET_LOCAL(simd1, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(b))),
+ WASM_SET_LOCAL(simd1,
+ WASM_SIMD_BINOP(simd_op & 0xffu, WASM_GET_LOCAL(simd0),
+ WASM_GET_LOCAL(simd1))),
+ WASM_SIMD_CHECK_SPLAT4(I32x4, simd1, I32, expected), WASM_ONE);
+
+ FOR_INT32_INPUTS(i) {
+ FOR_INT32_INPUTS(j) { CHECK_EQ(1, r.Call(*i, *j, expected_op(*i, *j))); }
+ }
+}
+
+WASM_EXEC_TEST(I32x4Add) { RunI32x4BinOpTest(kExprI32x4Add, Add); }
+
+WASM_EXEC_TEST(I32x4Sub) { RunI32x4BinOpTest(kExprI32x4Sub, Sub); }
+
+#if V8_TARGET_ARCH_ARM
+WASM_EXEC_TEST(I32x4Equal) { RunI32x4BinOpTest(kExprI32x4Eq, Equal); }
+
+WASM_EXEC_TEST(I32x4NotEqual) { RunI32x4BinOpTest(kExprI32x4Ne, NotEqual); }
+#endif // V8_TARGET_ARCH_ARM
diff --git a/deps/v8/test/cctest/wasm/test-run-wasm.cc b/deps/v8/test/cctest/wasm/test-run-wasm.cc
index a42a81ba27..05370b5775 100644
--- a/deps/v8/test/cctest/wasm/test-run-wasm.cc
+++ b/deps/v8/test/cctest/wasm/test-run-wasm.cc
@@ -25,41 +25,7 @@ using namespace v8::internal::wasm;
#define B2(a, b) WASM_BLOCK(a, b)
#define B3(a, b, c) WASM_BLOCK(a, b, c)
#define RET(x) x, kExprReturn
-#define RET_I8(x) kExprI8Const, x, kExprReturn
-
-WASM_EXEC_TEST(Int8Const) {
- WasmRunner<int32_t> r(execution_mode);
- const byte kExpectedValue = 121;
- // return(kExpectedValue)
- BUILD(r, WASM_I8(kExpectedValue));
- CHECK_EQ(kExpectedValue, r.Call());
-}
-
-WASM_EXEC_TEST(Int8Const_end) {
- WasmRunner<int32_t> r(execution_mode);
- const byte kExpectedValue = 121;
- // return(kExpectedValue)
- BUILD(r, WASM_I8(kExpectedValue), kExprEnd);
- CHECK_EQ(kExpectedValue, r.Call());
-}
-
-WASM_EXEC_TEST(Int8Const_fallthru2) {
- WasmRunner<int32_t> r(execution_mode);
- const byte kExpectedValue = 123;
- // -99 kExpectedValue
- BUILD(r, WASM_I8(-99), WASM_DROP, WASM_I8(kExpectedValue));
- CHECK_EQ(kExpectedValue, r.Call());
-}
-
-WASM_EXEC_TEST(Int8Const_all) {
- for (int value = -128; value <= 127; ++value) {
- WasmRunner<int32_t> r(execution_mode);
- // return(value)
- BUILD(r, WASM_I8(value));
- int32_t result = r.Call();
- CHECK_EQ(value, result);
- }
-}
+#define RET_I8(x) WASM_I32V_2(x), kExprReturn
WASM_EXEC_TEST(Int32Const) {
WasmRunner<int32_t> r(execution_mode);
@@ -81,29 +47,28 @@ WASM_EXEC_TEST(Int32Const_many) {
WASM_EXEC_TEST(GraphTrimming) {
// This WebAssembly code requires graph trimming in the TurboFan compiler.
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
BUILD(r, kExprGetLocal, 0, kExprGetLocal, 0, kExprGetLocal, 0, kExprI32RemS,
kExprI32Eq, kExprGetLocal, 0, kExprI32DivS, kExprUnreachable);
r.Call(1);
}
WASM_EXEC_TEST(Int32Param0) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
// return(local[0])
BUILD(r, WASM_GET_LOCAL(0));
FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
}
WASM_EXEC_TEST(Int32Param0_fallthru) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
// local[0]
BUILD(r, WASM_GET_LOCAL(0));
FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
}
WASM_EXEC_TEST(Int32Param1) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32(),
- MachineType::Int32());
+ WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
// local[1]
BUILD(r, WASM_GET_LOCAL(1));
FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(-111, *i)); }
@@ -112,28 +77,27 @@ WASM_EXEC_TEST(Int32Param1) {
WASM_EXEC_TEST(Int32Add) {
WasmRunner<int32_t> r(execution_mode);
// 11 + 44
- BUILD(r, WASM_I32_ADD(WASM_I8(11), WASM_I8(44)));
+ BUILD(r, WASM_I32_ADD(WASM_I32V_1(11), WASM_I32V_1(44)));
CHECK_EQ(55, r.Call());
}
WASM_EXEC_TEST(Int32Add_P) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
// p0 + 13
- BUILD(r, WASM_I32_ADD(WASM_I8(13), WASM_GET_LOCAL(0)));
+ BUILD(r, WASM_I32_ADD(WASM_I32V_1(13), WASM_GET_LOCAL(0)));
FOR_INT32_INPUTS(i) { CHECK_EQ(*i + 13, r.Call(*i)); }
}
WASM_EXEC_TEST(Int32Add_P_fallthru) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
// p0 + 13
- BUILD(r, WASM_I32_ADD(WASM_I8(13), WASM_GET_LOCAL(0)));
+ BUILD(r, WASM_I32_ADD(WASM_I32V_1(13), WASM_GET_LOCAL(0)));
FOR_INT32_INPUTS(i) { CHECK_EQ(*i + 13, r.Call(*i)); }
}
static void RunInt32AddTest(WasmExecutionMode execution_mode, const byte* code,
size_t size) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32(),
- MachineType::Int32());
+ WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
r.Build(code, code + size);
FOR_INT32_INPUTS(i) {
FOR_INT32_INPUTS(j) {
@@ -154,7 +118,7 @@ WASM_EXEC_TEST(Int32Add_P2) {
WASM_EXEC_TEST(Int32Add_block1) {
FLAG_wasm_mv_prototype = true;
static const byte code[] = {
- WASM_BLOCK_TT(kAstI32, kAstI32, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
+ WASM_BLOCK_TT(kWasmI32, kWasmI32, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
kExprI32Add};
RunInt32AddTest(execution_mode, code, sizeof(code));
}
@@ -162,7 +126,7 @@ WASM_EXEC_TEST(Int32Add_block1) {
WASM_EXEC_TEST(Int32Add_block2) {
FLAG_wasm_mv_prototype = true;
static const byte code[] = {
- WASM_BLOCK_TT(kAstI32, kAstI32, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
+ WASM_BLOCK_TT(kWasmI32, kWasmI32, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
kExprBr, DEPTH_0),
kExprI32Add};
RunInt32AddTest(execution_mode, code, sizeof(code));
@@ -171,7 +135,7 @@ WASM_EXEC_TEST(Int32Add_block2) {
WASM_EXEC_TEST(Int32Add_multi_if) {
FLAG_wasm_mv_prototype = true;
static const byte code[] = {
- WASM_IF_ELSE_TT(kAstI32, kAstI32, WASM_GET_LOCAL(0),
+ WASM_IF_ELSE_TT(kWasmI32, kWasmI32, WASM_GET_LOCAL(0),
WASM_SEQ(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)),
WASM_SEQ(WASM_GET_LOCAL(1), WASM_GET_LOCAL(0))),
kExprI32Add};
@@ -202,8 +166,7 @@ void TestInt32Binop(WasmExecutionMode execution_mode, WasmOpcode opcode,
CHECK_EQ(expected, r.Call());
}
{
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32(),
- MachineType::Int32());
+ WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
// a op b
BUILD(r, WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
CHECK_EQ(expected, r.Call(a, b));
@@ -252,7 +215,7 @@ void TestInt32Unop(WasmExecutionMode execution_mode, WasmOpcode opcode,
CHECK_EQ(expected, r.Call());
}
{
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
// return op a
BUILD(r, WASM_UNOP(opcode, WASM_GET_LOCAL(0)));
CHECK_EQ(expected, r.Call(a));
@@ -348,8 +311,7 @@ WASM_EXEC_TEST(I32Eqz) {
}
WASM_EXEC_TEST(I32Shl) {
- WasmRunner<uint32_t> r(execution_mode, MachineType::Uint32(),
- MachineType::Uint32());
+ WasmRunner<uint32_t, uint32_t, uint32_t> r(execution_mode);
BUILD(r, WASM_I32_SHL(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_UINT32_INPUTS(i) {
@@ -361,8 +323,7 @@ WASM_EXEC_TEST(I32Shl) {
}
WASM_EXEC_TEST(I32Shr) {
- WasmRunner<uint32_t> r(execution_mode, MachineType::Uint32(),
- MachineType::Uint32());
+ WasmRunner<uint32_t, uint32_t, uint32_t> r(execution_mode);
BUILD(r, WASM_I32_SHR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_UINT32_INPUTS(i) {
@@ -374,8 +335,7 @@ WASM_EXEC_TEST(I32Shr) {
}
WASM_EXEC_TEST(I32Sar) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32(),
- MachineType::Int32());
+ WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
BUILD(r, WASM_I32_SAR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_INT32_INPUTS(i) {
@@ -386,9 +346,8 @@ WASM_EXEC_TEST(I32Sar) {
}
}
-WASM_EXEC_TEST(Int32DivS_trap) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32(),
- MachineType::Int32());
+WASM_EXEC_TEST_WITH_TRAP(Int32DivS_trap) {
+ WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
BUILD(r, WASM_I32_DIVS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
const int32_t kMin = std::numeric_limits<int32_t>::min();
CHECK_EQ(0, r.Call(0, 100));
@@ -398,9 +357,8 @@ WASM_EXEC_TEST(Int32DivS_trap) {
CHECK_TRAP(r.Call(kMin, 0));
}
-WASM_EXEC_TEST(Int32RemS_trap) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32(),
- MachineType::Int32());
+WASM_EXEC_TEST_WITH_TRAP(Int32RemS_trap) {
+ WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
BUILD(r, WASM_I32_REMS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
const int32_t kMin = std::numeric_limits<int32_t>::min();
CHECK_EQ(33, r.Call(133, 100));
@@ -410,9 +368,8 @@ WASM_EXEC_TEST(Int32RemS_trap) {
CHECK_TRAP(r.Call(kMin, 0));
}
-WASM_EXEC_TEST(Int32DivU_trap) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32(),
- MachineType::Int32());
+WASM_EXEC_TEST_WITH_TRAP(Int32DivU_trap) {
+ WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
BUILD(r, WASM_I32_DIVU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
const int32_t kMin = std::numeric_limits<int32_t>::min();
CHECK_EQ(0, r.Call(0, 100));
@@ -422,9 +379,8 @@ WASM_EXEC_TEST(Int32DivU_trap) {
CHECK_TRAP(r.Call(kMin, 0));
}
-WASM_EXEC_TEST(Int32RemU_trap) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32(),
- MachineType::Int32());
+WASM_EXEC_TEST_WITH_TRAP(Int32RemU_trap) {
+ WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
BUILD(r, WASM_I32_REMU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
CHECK_EQ(17, r.Call(217, 100));
const int32_t kMin = std::numeric_limits<int32_t>::min();
@@ -434,10 +390,10 @@ WASM_EXEC_TEST(Int32RemU_trap) {
CHECK_EQ(kMin, r.Call(kMin, -1));
}
-WASM_EXEC_TEST(Int32DivS_byzero_const) {
+WASM_EXEC_TEST_WITH_TRAP(Int32DivS_byzero_const) {
for (int8_t denom = -2; denom < 8; ++denom) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
- BUILD(r, WASM_I32_DIVS(WASM_GET_LOCAL(0), WASM_I8(denom)));
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ BUILD(r, WASM_I32_DIVS(WASM_GET_LOCAL(0), WASM_I32V_1(denom)));
for (int32_t val = -7; val < 8; ++val) {
if (denom == 0) {
CHECK_TRAP(r.Call(val));
@@ -450,10 +406,9 @@ WASM_EXEC_TEST(Int32DivS_byzero_const) {
WASM_EXEC_TEST(Int32AsmjsDivS_byzero_const) {
for (int8_t denom = -2; denom < 8; ++denom) {
- TestingModule module(execution_mode);
- module.ChangeOriginToAsmjs();
- WasmRunner<int32_t> r(&module, MachineType::Int32());
- BUILD(r, WASM_I32_ASMJS_DIVS(WASM_GET_LOCAL(0), WASM_I8(denom)));
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ r.module().ChangeOriginToAsmjs();
+ BUILD(r, WASM_I32_ASMJS_DIVS(WASM_GET_LOCAL(0), WASM_I32V_1(denom)));
FOR_INT32_INPUTS(i) {
if (denom == 0) {
CHECK_EQ(0, r.Call(*i));
@@ -468,10 +423,9 @@ WASM_EXEC_TEST(Int32AsmjsDivS_byzero_const) {
WASM_EXEC_TEST(Int32AsmjsRemS_byzero_const) {
for (int8_t denom = -2; denom < 8; ++denom) {
- TestingModule module(execution_mode);
- module.ChangeOriginToAsmjs();
- WasmRunner<int32_t> r(&module, MachineType::Int32());
- BUILD(r, WASM_I32_ASMJS_REMS(WASM_GET_LOCAL(0), WASM_I8(denom)));
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ r.module().ChangeOriginToAsmjs();
+ BUILD(r, WASM_I32_ASMJS_REMS(WASM_GET_LOCAL(0), WASM_I32V_1(denom)));
FOR_INT32_INPUTS(i) {
if (denom == 0) {
CHECK_EQ(0, r.Call(*i));
@@ -484,9 +438,9 @@ WASM_EXEC_TEST(Int32AsmjsRemS_byzero_const) {
}
}
-WASM_EXEC_TEST(Int32DivU_byzero_const) {
+WASM_EXEC_TEST_WITH_TRAP(Int32DivU_byzero_const) {
for (uint32_t denom = 0xfffffffe; denom < 8; ++denom) {
- WasmRunner<uint32_t> r(execution_mode, MachineType::Uint32());
+ WasmRunner<uint32_t, uint32_t> r(execution_mode);
BUILD(r, WASM_I32_DIVU(WASM_GET_LOCAL(0), WASM_I32V_1(denom)));
for (uint32_t val = 0xfffffff0; val < 8; ++val) {
@@ -499,10 +453,9 @@ WASM_EXEC_TEST(Int32DivU_byzero_const) {
}
}
-WASM_EXEC_TEST(Int32DivS_trap_effect) {
- TestingModule module(execution_mode);
- module.AddMemoryElems<int32_t>(8);
- WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32());
+WASM_EXEC_TEST_WITH_TRAP(Int32DivS_trap_effect) {
+ WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
+ r.module().AddMemoryElems<int32_t>(8);
BUILD(r, WASM_IF_ELSE_I(
WASM_GET_LOCAL(0),
@@ -531,8 +484,7 @@ void TestFloat32Binop(WasmExecutionMode execution_mode, WasmOpcode opcode,
CHECK_EQ(expected, r.Call());
}
{
- WasmRunner<int32_t> r(execution_mode, MachineType::Float32(),
- MachineType::Float32());
+ WasmRunner<int32_t, float, float> r(execution_mode);
// return a op b
BUILD(r, WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
CHECK_EQ(expected, r.Call(a, b));
@@ -550,8 +502,7 @@ void TestFloat32BinopWithConvert(WasmExecutionMode execution_mode,
CHECK_EQ(expected, r.Call());
}
{
- WasmRunner<int32_t> r(execution_mode, MachineType::Float32(),
- MachineType::Float32());
+ WasmRunner<int32_t, float, float> r(execution_mode);
// return int(a op b)
BUILD(r, WASM_I32_SCONVERT_F32(
WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))));
@@ -568,7 +519,7 @@ void TestFloat32UnopWithConvert(WasmExecutionMode execution_mode,
CHECK_EQ(expected, r.Call());
}
{
- WasmRunner<int32_t> r(execution_mode, MachineType::Float32());
+ WasmRunner<int32_t, float> r(execution_mode);
// return int(op(a))
BUILD(r, WASM_I32_SCONVERT_F32(WASM_UNOP(opcode, WASM_GET_LOCAL(0))));
CHECK_EQ(expected, r.Call(a));
@@ -584,8 +535,7 @@ void TestFloat64Binop(WasmExecutionMode execution_mode, WasmOpcode opcode,
CHECK_EQ(expected, r.Call());
}
{
- WasmRunner<int32_t> r(execution_mode, MachineType::Float64(),
- MachineType::Float64());
+ WasmRunner<int32_t, double, double> r(execution_mode);
// return a op b
BUILD(r, WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
CHECK_EQ(expected, r.Call(a, b));
@@ -603,8 +553,7 @@ void TestFloat64BinopWithConvert(WasmExecutionMode execution_mode,
CHECK_EQ(expected, r.Call());
}
{
- WasmRunner<int32_t> r(execution_mode, MachineType::Float64(),
- MachineType::Float64());
+ WasmRunner<int32_t, double, double> r(execution_mode);
BUILD(r, WASM_I32_SCONVERT_F64(
WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))));
CHECK_EQ(expected, r.Call(a, b));
@@ -620,7 +569,7 @@ void TestFloat64UnopWithConvert(WasmExecutionMode execution_mode,
CHECK_EQ(expected, r.Call());
}
{
- WasmRunner<int32_t> r(execution_mode, MachineType::Float64());
+ WasmRunner<int32_t, double> r(execution_mode);
// return int(op(a))
BUILD(r, WASM_I32_SCONVERT_F64(WASM_UNOP(opcode, WASM_GET_LOCAL(0))));
CHECK_EQ(expected, r.Call(a));
@@ -671,7 +620,7 @@ WASM_EXEC_TEST(Float64Unops) {
}
WASM_EXEC_TEST(Float32Neg) {
- WasmRunner<float> r(execution_mode, MachineType::Float32());
+ WasmRunner<float, float> r(execution_mode);
BUILD(r, WASM_F32_NEG(WASM_GET_LOCAL(0)));
FOR_FLOAT32_INPUTS(i) {
@@ -681,7 +630,7 @@ WASM_EXEC_TEST(Float32Neg) {
}
WASM_EXEC_TEST(Float64Neg) {
- WasmRunner<double> r(execution_mode, MachineType::Float64());
+ WasmRunner<double, double> r(execution_mode);
BUILD(r, WASM_F64_NEG(WASM_GET_LOCAL(0)));
FOR_FLOAT64_INPUTS(i) {
@@ -691,11 +640,11 @@ WASM_EXEC_TEST(Float64Neg) {
}
WASM_EXEC_TEST(IfElse_P) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
// if (p0) return 11; else return 22;
BUILD(r, WASM_IF_ELSE_I(WASM_GET_LOCAL(0), // --
- WASM_I8(11), // --
- WASM_I8(22))); // --
+ WASM_I32V_1(11), // --
+ WASM_I32V_1(22))); // --
FOR_INT32_INPUTS(i) {
int32_t expected = *i ? 11 : 22;
CHECK_EQ(expected, r.Call(*i));
@@ -704,50 +653,45 @@ WASM_EXEC_TEST(IfElse_P) {
#define EMPTY
WASM_EXEC_TEST(If_empty1) {
- WasmRunner<uint32_t> r(execution_mode, MachineType::Uint32(),
- MachineType::Uint32());
+ WasmRunner<uint32_t, uint32_t, uint32_t> r(execution_mode);
BUILD(r, WASM_GET_LOCAL(0), kExprIf, kLocalVoid, kExprEnd, WASM_GET_LOCAL(1));
FOR_UINT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i - 9, *i)); }
}
WASM_EXEC_TEST(IfElse_empty1) {
- WasmRunner<uint32_t> r(execution_mode, MachineType::Uint32(),
- MachineType::Uint32());
+ WasmRunner<uint32_t, uint32_t, uint32_t> r(execution_mode);
BUILD(r, WASM_GET_LOCAL(0), kExprIf, kLocalVoid, kExprElse, kExprEnd,
WASM_GET_LOCAL(1));
FOR_UINT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i - 8, *i)); }
}
WASM_EXEC_TEST(IfElse_empty2) {
- WasmRunner<uint32_t> r(execution_mode, MachineType::Uint32(),
- MachineType::Uint32());
+ WasmRunner<uint32_t, uint32_t, uint32_t> r(execution_mode);
BUILD(r, WASM_GET_LOCAL(0), kExprIf, kLocalVoid, WASM_NOP, kExprElse,
kExprEnd, WASM_GET_LOCAL(1));
FOR_UINT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i - 7, *i)); }
}
WASM_EXEC_TEST(IfElse_empty3) {
- WasmRunner<uint32_t> r(execution_mode, MachineType::Uint32(),
- MachineType::Uint32());
+ WasmRunner<uint32_t, uint32_t, uint32_t> r(execution_mode);
BUILD(r, WASM_GET_LOCAL(0), kExprIf, kLocalVoid, kExprElse, WASM_NOP,
kExprEnd, WASM_GET_LOCAL(1));
FOR_UINT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i - 6, *i)); }
}
WASM_EXEC_TEST(If_chain1) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
// if (p0) 13; if (p0) 14; 15
BUILD(r, WASM_IF(WASM_GET_LOCAL(0), WASM_NOP),
- WASM_IF(WASM_GET_LOCAL(0), WASM_NOP), WASM_I8(15));
+ WASM_IF(WASM_GET_LOCAL(0), WASM_NOP), WASM_I32V_1(15));
FOR_INT32_INPUTS(i) { CHECK_EQ(15, r.Call(*i)); }
}
WASM_EXEC_TEST(If_chain_set) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32(),
- MachineType::Int32());
+ WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
// if (p0) p1 = 73; if (p0) p1 = 74; p1
- BUILD(r, WASM_IF(WASM_GET_LOCAL(0), WASM_SET_LOCAL(1, WASM_I8(73))),
- WASM_IF(WASM_GET_LOCAL(0), WASM_SET_LOCAL(1, WASM_I8(74))),
+ BUILD(r, WASM_IF(WASM_GET_LOCAL(0), WASM_SET_LOCAL(1, WASM_I32V_2(73))),
+ WASM_IF(WASM_GET_LOCAL(0), WASM_SET_LOCAL(1, WASM_I32V_2(74))),
WASM_GET_LOCAL(1));
FOR_INT32_INPUTS(i) {
int32_t expected = *i ? 74 : *i;
@@ -758,17 +702,17 @@ WASM_EXEC_TEST(If_chain_set) {
WASM_EXEC_TEST(IfElse_Unreachable1) {
WasmRunner<int32_t> r(execution_mode);
// 0 ? unreachable : 27
- BUILD(r, WASM_IF_ELSE_I(WASM_ZERO, // --
- WASM_UNREACHABLE, // --
- WASM_I8(27))); // --
+ BUILD(r, WASM_IF_ELSE_I(WASM_ZERO, // --
+ WASM_UNREACHABLE, // --
+ WASM_I32V_1(27))); // --
CHECK_EQ(27, r.Call());
}
WASM_EXEC_TEST(IfElse_Unreachable2) {
WasmRunner<int32_t> r(execution_mode);
// 1 ? 28 : unreachable
- BUILD(r, WASM_IF_ELSE_I(WASM_I8(1), // --
- WASM_I8(28), // --
+ BUILD(r, WASM_IF_ELSE_I(WASM_I32V_1(1), // --
+ WASM_I32V_1(28), // --
WASM_UNREACHABLE)); // --
CHECK_EQ(28, r.Call());
}
@@ -783,12 +727,12 @@ WASM_EXEC_TEST(Return12) {
WASM_EXEC_TEST(Return17) {
WasmRunner<int32_t> r(execution_mode);
- BUILD(r, WASM_BLOCK(RET_I8(17)));
+ BUILD(r, WASM_BLOCK(RET_I8(17)), WASM_ZERO);
CHECK_EQ(17, r.Call());
}
WASM_EXEC_TEST(Return_I32) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
BUILD(r, RET(WASM_GET_LOCAL(0)));
@@ -796,7 +740,7 @@ WASM_EXEC_TEST(Return_I32) {
}
WASM_EXEC_TEST(Return_F32) {
- WasmRunner<float> r(execution_mode, MachineType::Float32());
+ WasmRunner<float, float> r(execution_mode);
BUILD(r, RET(WASM_GET_LOCAL(0)));
@@ -812,7 +756,7 @@ WASM_EXEC_TEST(Return_F32) {
}
WASM_EXEC_TEST(Return_F64) {
- WasmRunner<double> r(execution_mode, MachineType::Float64());
+ WasmRunner<double, double> r(execution_mode);
BUILD(r, RET(WASM_GET_LOCAL(0)));
@@ -828,8 +772,7 @@ WASM_EXEC_TEST(Return_F64) {
}
WASM_EXEC_TEST(Select_float_parameters) {
- WasmRunner<float> r(execution_mode, MachineType::Float32(),
- MachineType::Float32(), MachineType::Int32());
+ WasmRunner<float, float, float, int32_t> r(execution_mode);
// return select(11, 22, a);
BUILD(r,
WASM_SELECT(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1), WASM_GET_LOCAL(2)));
@@ -837,9 +780,9 @@ WASM_EXEC_TEST(Select_float_parameters) {
}
WASM_EXEC_TEST(Select) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
// return select(11, 22, a);
- BUILD(r, WASM_SELECT(WASM_I8(11), WASM_I8(22), WASM_GET_LOCAL(0)));
+ BUILD(r, WASM_SELECT(WASM_I32V_1(11), WASM_I32V_1(22), WASM_GET_LOCAL(0)));
FOR_INT32_INPUTS(i) {
int32_t expected = *i ? 11 : 22;
CHECK_EQ(expected, r.Call(*i));
@@ -847,22 +790,22 @@ WASM_EXEC_TEST(Select) {
}
WASM_EXEC_TEST(Select_strict1) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
// select(a=0, a=1, a=2); return a
- BUILD(r, WASM_SELECT(WASM_TEE_LOCAL(0, WASM_I8(0)),
- WASM_TEE_LOCAL(0, WASM_I8(1)),
- WASM_TEE_LOCAL(0, WASM_I8(2))),
+ BUILD(r, WASM_SELECT(WASM_TEE_LOCAL(0, WASM_ZERO),
+ WASM_TEE_LOCAL(0, WASM_I32V_1(1)),
+ WASM_TEE_LOCAL(0, WASM_I32V_1(2))),
WASM_DROP, WASM_GET_LOCAL(0));
FOR_INT32_INPUTS(i) { CHECK_EQ(2, r.Call(*i)); }
}
WASM_EXEC_TEST(Select_strict2) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
- r.AllocateLocal(kAstI32);
- r.AllocateLocal(kAstI32);
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ r.AllocateLocal(kWasmI32);
+ r.AllocateLocal(kWasmI32);
// select(b=5, c=6, a)
- BUILD(r, WASM_SELECT(WASM_TEE_LOCAL(1, WASM_I8(5)),
- WASM_TEE_LOCAL(2, WASM_I8(6)), WASM_GET_LOCAL(0)));
+ BUILD(r, WASM_SELECT(WASM_TEE_LOCAL(1, WASM_I32V_1(5)),
+ WASM_TEE_LOCAL(2, WASM_I32V_1(6)), WASM_GET_LOCAL(0)));
FOR_INT32_INPUTS(i) {
int32_t expected = *i ? 5 : 6;
CHECK_EQ(expected, r.Call(*i));
@@ -870,12 +813,12 @@ WASM_EXEC_TEST(Select_strict2) {
}
WASM_EXEC_TEST(Select_strict3) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
- r.AllocateLocal(kAstI32);
- r.AllocateLocal(kAstI32);
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ r.AllocateLocal(kWasmI32);
+ r.AllocateLocal(kWasmI32);
// select(b=5, c=6, a=b)
- BUILD(r, WASM_SELECT(WASM_TEE_LOCAL(1, WASM_I8(5)),
- WASM_TEE_LOCAL(2, WASM_I8(6)),
+ BUILD(r, WASM_SELECT(WASM_TEE_LOCAL(1, WASM_I32V_1(5)),
+ WASM_TEE_LOCAL(2, WASM_I32V_1(6)),
WASM_TEE_LOCAL(0, WASM_GET_LOCAL(1))));
FOR_INT32_INPUTS(i) {
int32_t expected = 5;
@@ -884,20 +827,19 @@ WASM_EXEC_TEST(Select_strict3) {
}
WASM_EXEC_TEST(BrIf_strict) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
BUILD(r, WASM_BLOCK_I(WASM_BRV_IF(0, WASM_GET_LOCAL(0),
- WASM_TEE_LOCAL(0, WASM_I8(99)))));
+ WASM_TEE_LOCAL(0, WASM_I32V_2(99)))));
FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
}
WASM_EXEC_TEST(Br_height) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
- BUILD(r,
- WASM_BLOCK_I(
- WASM_BLOCK_I(WASM_BRV_IFD(0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(0)),
- WASM_RETURN1(WASM_I8(9)), WASM_I8(7), WASM_I8(7)),
- WASM_BRV(0, WASM_I8(8))));
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ BUILD(r, WASM_BLOCK_I(
+ WASM_BLOCK(WASM_BRV_IFD(0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(0)),
+ WASM_RETURN1(WASM_I32V_1(9))),
+ WASM_BRV(0, WASM_I32V_1(8))));
for (int32_t i = 0; i < 5; i++) {
int32_t expected = i != 0 ? 8 : 9;
@@ -906,36 +848,35 @@ WASM_EXEC_TEST(Br_height) {
}
WASM_EXEC_TEST(Regression_660262) {
- TestingModule module(execution_mode);
- module.AddMemoryElems<int32_t>(8);
- WasmRunner<int32_t> r(&module);
- BUILD(r, kExprI8Const, 0x00, kExprI8Const, 0x00, kExprI32LoadMem, 0x00, 0x0f,
- kExprBrTable, 0x00, 0x80, 0x00); // entries=0
+ WasmRunner<int32_t> r(execution_mode);
+ r.module().AddMemoryElems<int32_t>(8);
+ BUILD(r, kExprI32Const, 0x00, kExprI32Const, 0x00, kExprI32LoadMem, 0x00,
+ 0x0f, kExprBrTable, 0x00, 0x80, 0x00); // entries=0
r.Call();
}
WASM_EXEC_TEST(BrTable0a) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
BUILD(r, B1(B1(WASM_BR_TABLE(WASM_GET_LOCAL(0), 0, BR_TARGET(0)))),
- WASM_I8(91));
+ WASM_I32V_2(91));
FOR_INT32_INPUTS(i) { CHECK_EQ(91, r.Call(*i)); }
}
WASM_EXEC_TEST(BrTable0b) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
BUILD(r,
B1(B1(WASM_BR_TABLE(WASM_GET_LOCAL(0), 1, BR_TARGET(0), BR_TARGET(0)))),
- WASM_I8(92));
+ WASM_I32V_2(92));
FOR_INT32_INPUTS(i) { CHECK_EQ(92, r.Call(*i)); }
}
WASM_EXEC_TEST(BrTable0c) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
BUILD(
r,
B1(B2(B1(WASM_BR_TABLE(WASM_GET_LOCAL(0), 1, BR_TARGET(0), BR_TARGET(1))),
RET_I8(76))),
- WASM_I8(77));
+ WASM_I32V_2(77));
FOR_INT32_INPUTS(i) {
int32_t expected = *i == 0 ? 76 : 77;
CHECK_EQ(expected, r.Call(*i));
@@ -943,18 +884,18 @@ WASM_EXEC_TEST(BrTable0c) {
}
WASM_EXEC_TEST(BrTable1) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
BUILD(r, B1(WASM_BR_TABLE(WASM_GET_LOCAL(0), 0, BR_TARGET(0))), RET_I8(93));
FOR_INT32_INPUTS(i) { CHECK_EQ(93, r.Call(*i)); }
}
WASM_EXEC_TEST(BrTable_loop) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
BUILD(r,
B2(B1(WASM_LOOP(WASM_BR_TABLE(WASM_INC_LOCAL_BYV(0, 1), 2, BR_TARGET(2),
BR_TARGET(1), BR_TARGET(0)))),
RET_I8(99)),
- WASM_I8(98));
+ WASM_I32V_2(98));
CHECK_EQ(99, r.Call(0));
CHECK_EQ(98, r.Call(-1));
CHECK_EQ(98, r.Call(-2));
@@ -963,11 +904,11 @@ WASM_EXEC_TEST(BrTable_loop) {
}
WASM_EXEC_TEST(BrTable_br) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
BUILD(r,
B2(B1(WASM_BR_TABLE(WASM_GET_LOCAL(0), 1, BR_TARGET(1), BR_TARGET(0))),
RET_I8(91)),
- WASM_I8(99));
+ WASM_I32V_2(99));
CHECK_EQ(99, r.Call(0));
CHECK_EQ(91, r.Call(1));
CHECK_EQ(91, r.Call(2));
@@ -975,14 +916,14 @@ WASM_EXEC_TEST(BrTable_br) {
}
WASM_EXEC_TEST(BrTable_br2) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
BUILD(r, B2(B2(B2(B1(WASM_BR_TABLE(WASM_GET_LOCAL(0), 3, BR_TARGET(1),
BR_TARGET(2), BR_TARGET(3), BR_TARGET(0))),
RET_I8(85)),
RET_I8(86)),
RET_I8(87)),
- WASM_I8(88));
+ WASM_I32V_2(88));
CHECK_EQ(86, r.Call(0));
CHECK_EQ(87, r.Call(1));
CHECK_EQ(88, r.Call(2));
@@ -1004,9 +945,9 @@ WASM_EXEC_TEST(BrTable4) {
RET_I8(71)),
RET_I8(72)),
RET_I8(73)),
- WASM_I8(75)};
+ WASM_I32V_2(75)};
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
r.Build(code, code + arraysize(code));
for (int x = -3; x < 50; ++x) {
@@ -1034,9 +975,9 @@ WASM_EXEC_TEST(BrTable4x4) {
RET_I8(51)),
RET_I8(52)),
RET_I8(53)),
- WASM_I8(55)};
+ WASM_I32V_2(55)};
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
r.Build(code, code + arraysize(code));
for (int x = -6; x < 47; ++x) {
@@ -1061,8 +1002,7 @@ WASM_EXEC_TEST(BrTable4_fallthru) {
WASM_INC_LOCAL_BY(1, 8)),
WASM_GET_LOCAL(1)};
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32(),
- MachineType::Int32());
+ WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
r.Build(code, code + arraysize(code));
CHECK_EQ(15, r.Call(0, 0));
@@ -1079,42 +1019,49 @@ WASM_EXEC_TEST(BrTable4_fallthru) {
}
WASM_EXEC_TEST(F32ReinterpretI32) {
- TestingModule module(execution_mode);
- int32_t* memory = module.AddMemoryElems<int32_t>(8);
- WasmRunner<int32_t> r(&module);
+ WasmRunner<int32_t> r(execution_mode);
+ int32_t* memory = r.module().AddMemoryElems<int32_t>(8);
BUILD(r, WASM_I32_REINTERPRET_F32(
WASM_LOAD_MEM(MachineType::Float32(), WASM_ZERO)));
FOR_INT32_INPUTS(i) {
int32_t expected = *i;
- module.WriteMemory(&memory[0], expected);
+ r.module().WriteMemory(&memory[0], expected);
CHECK_EQ(expected, r.Call());
}
}
WASM_EXEC_TEST(I32ReinterpretF32) {
- TestingModule module(execution_mode);
- int32_t* memory = module.AddMemoryElems<int32_t>(8);
- WasmRunner<int32_t> r(&module, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ int32_t* memory = r.module().AddMemoryElems<int32_t>(8);
BUILD(r, WASM_STORE_MEM(MachineType::Float32(), WASM_ZERO,
WASM_F32_REINTERPRET_I32(WASM_GET_LOCAL(0))),
- WASM_I8(107));
+ WASM_I32V_2(107));
FOR_INT32_INPUTS(i) {
int32_t expected = *i;
CHECK_EQ(107, r.Call(expected));
- CHECK_EQ(expected, module.ReadMemory(&memory[0]));
+ CHECK_EQ(expected, r.module().ReadMemory(&memory[0]));
}
}
-WASM_EXEC_TEST(LoadMaxUint32Offset) {
- TestingModule module(execution_mode);
- module.AddMemoryElems<int32_t>(8);
- WasmRunner<int32_t> r(&module);
+WASM_EXEC_TEST(SignallingNanSurvivesI32ReinterpretF32) {
+ WasmRunner<int32_t> r(execution_mode);
+
+ BUILD(r, WASM_I32_REINTERPRET_F32(
+ WASM_SEQ(kExprF32Const, 0x00, 0x00, 0xa0, 0x7f)));
+
+ // This is a signalling nan.
+ CHECK_EQ(0x7fa00000, r.Call());
+}
+
+WASM_EXEC_TEST_WITH_TRAP(LoadMaxUint32Offset) {
+ WasmRunner<int32_t> r(execution_mode);
+ r.module().AddMemoryElems<int32_t>(8);
- BUILD(r, kExprI8Const, 0, // index
+ BUILD(r, kExprI32Const, 0, // index
static_cast<byte>(v8::internal::wasm::WasmOpcodes::LoadStoreOpcodeOf(
MachineType::Int32(), false)), // --
0, // alignment
@@ -1124,9 +1071,8 @@ WASM_EXEC_TEST(LoadMaxUint32Offset) {
}
WASM_EXEC_TEST(LoadStoreLoad) {
- TestingModule module(execution_mode);
- int32_t* memory = module.AddMemoryElems<int32_t>(8);
- WasmRunner<int32_t> r(&module);
+ WasmRunner<int32_t> r(execution_mode);
+ int32_t* memory = r.module().AddMemoryElems<int32_t>(8);
BUILD(r, WASM_STORE_MEM(MachineType::Int32(), WASM_ZERO,
WASM_LOAD_MEM(MachineType::Int32(), WASM_ZERO)),
@@ -1134,116 +1080,112 @@ WASM_EXEC_TEST(LoadStoreLoad) {
FOR_INT32_INPUTS(i) {
int32_t expected = *i;
- module.WriteMemory(&memory[0], expected);
+ r.module().WriteMemory(&memory[0], expected);
CHECK_EQ(expected, r.Call());
}
}
WASM_EXEC_TEST(VoidReturn1) {
- // We use a wrapper function because WasmRunner<void> does not exist.
+ const int32_t kExpected = -414444;
+ WasmRunner<int32_t> r(execution_mode);
// Build the test function.
- TestSignatures sigs;
- TestingModule module(execution_mode);
- WasmFunctionCompiler t(sigs.v_v(), &module);
- BUILD(t, kExprNop);
- uint32_t index = t.CompileAndAdd();
+ WasmFunctionCompiler& test_func = r.NewFunction<void>();
+ BUILD(test_func, kExprNop);
- const int32_t kExpected = -414444;
// Build the calling function.
- WasmRunner<int32_t> r(&module);
- BUILD(r, WASM_CALL_FUNCTION0(index), WASM_I32V_3(kExpected));
+ BUILD(r, WASM_CALL_FUNCTION0(test_func.function_index()),
+ WASM_I32V_3(kExpected));
+ // Call and check.
int32_t result = r.Call();
CHECK_EQ(kExpected, result);
}
WASM_EXEC_TEST(VoidReturn2) {
- // We use a wrapper function because WasmRunner<void> does not exist.
+ const int32_t kExpected = -414444;
+ WasmRunner<int32_t> r(execution_mode);
+
// Build the test function.
- TestSignatures sigs;
- TestingModule module(execution_mode);
- WasmFunctionCompiler t(sigs.v_v(), &module);
- BUILD(t, WASM_RETURN0);
- uint32_t index = t.CompileAndAdd();
+ WasmFunctionCompiler& test_func = r.NewFunction<void>();
+ BUILD(test_func, WASM_RETURN0);
- const int32_t kExpected = -414444;
// Build the calling function.
- WasmRunner<int32_t> r(&module);
- BUILD(r, B1(WASM_CALL_FUNCTION0(index)), WASM_I32V_3(kExpected));
+ BUILD(r, WASM_CALL_FUNCTION0(test_func.function_index()),
+ WASM_I32V_3(kExpected));
+ // Call and check.
int32_t result = r.Call();
CHECK_EQ(kExpected, result);
}
WASM_EXEC_TEST(BrEmpty) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
BUILD(r, WASM_BRV(0, WASM_GET_LOCAL(0)));
FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
}
WASM_EXEC_TEST(BrIfEmpty) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
BUILD(r, WASM_BRV_IF(0, WASM_GET_LOCAL(0), WASM_GET_LOCAL(0)));
FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
}
WASM_EXEC_TEST(Block_empty) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
BUILD(r, kExprBlock, kLocalVoid, kExprEnd, WASM_GET_LOCAL(0));
FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
}
WASM_EXEC_TEST(Block_empty_br1) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
BUILD(r, B1(WASM_BR(0)), WASM_GET_LOCAL(0));
FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
}
WASM_EXEC_TEST(Block_empty_brif1) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
BUILD(r, WASM_BLOCK(WASM_BR_IF(0, WASM_ZERO)), WASM_GET_LOCAL(0));
FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
}
WASM_EXEC_TEST(Block_empty_brif2) {
- WasmRunner<uint32_t> r(execution_mode, MachineType::Uint32(),
- MachineType::Uint32());
+ WasmRunner<uint32_t, uint32_t, uint32_t> r(execution_mode);
BUILD(r, WASM_BLOCK(WASM_BR_IF(0, WASM_GET_LOCAL(1))), WASM_GET_LOCAL(0));
FOR_UINT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i, *i + 1)); }
}
WASM_EXEC_TEST(Block_i) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
BUILD(r, WASM_BLOCK_I(WASM_GET_LOCAL(0)));
FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
}
WASM_EXEC_TEST(Block_f) {
- WasmRunner<float> r(execution_mode, MachineType::Float32());
+ WasmRunner<float, float> r(execution_mode);
BUILD(r, WASM_BLOCK_F(WASM_GET_LOCAL(0)));
FOR_FLOAT32_INPUTS(i) { CHECK_FLOAT_EQ(*i, r.Call(*i)); }
}
WASM_EXEC_TEST(Block_d) {
- WasmRunner<double> r(execution_mode, MachineType::Float64());
+ WasmRunner<double, double> r(execution_mode);
BUILD(r, WASM_BLOCK_D(WASM_GET_LOCAL(0)));
FOR_FLOAT64_INPUTS(i) { CHECK_FLOAT_EQ(*i, r.Call(*i)); }
}
WASM_EXEC_TEST(Block_br2) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
BUILD(r, WASM_BLOCK_I(WASM_BRV(0, WASM_GET_LOCAL(0))));
FOR_UINT32_INPUTS(i) { CHECK_EQ(*i, static_cast<uint32_t>(r.Call(*i))); }
}
WASM_EXEC_TEST(Block_If_P) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
// block { if (p0) break 51; 52; }
- BUILD(r, WASM_BLOCK_I( // --
- WASM_IF(WASM_GET_LOCAL(0), // --
- WASM_BRV(1, WASM_I8(51))), // --
- WASM_I8(52))); // --
+ BUILD(r, WASM_BLOCK_I( // --
+ WASM_IF(WASM_GET_LOCAL(0), // --
+ WASM_BRV(1, WASM_I32V_1(51))), // --
+ WASM_I32V_1(52))); // --
FOR_INT32_INPUTS(i) {
int32_t expected = *i ? 51 : 52;
CHECK_EQ(expected, r.Call(*i));
@@ -1251,51 +1193,49 @@ WASM_EXEC_TEST(Block_If_P) {
}
WASM_EXEC_TEST(Loop_empty) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
BUILD(r, kExprLoop, kLocalVoid, kExprEnd, WASM_GET_LOCAL(0));
FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
}
WASM_EXEC_TEST(Loop_i) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
BUILD(r, WASM_LOOP_I(WASM_GET_LOCAL(0)));
FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
}
WASM_EXEC_TEST(Loop_f) {
- WasmRunner<float> r(execution_mode, MachineType::Float32());
+ WasmRunner<float, float> r(execution_mode);
BUILD(r, WASM_LOOP_F(WASM_GET_LOCAL(0)));
FOR_FLOAT32_INPUTS(i) { CHECK_FLOAT_EQ(*i, r.Call(*i)); }
}
WASM_EXEC_TEST(Loop_d) {
- WasmRunner<double> r(execution_mode, MachineType::Float64());
+ WasmRunner<double, double> r(execution_mode);
BUILD(r, WASM_LOOP_D(WASM_GET_LOCAL(0)));
FOR_FLOAT64_INPUTS(i) { CHECK_FLOAT_EQ(*i, r.Call(*i)); }
}
WASM_EXEC_TEST(Loop_empty_br1) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
BUILD(r, B1(WASM_LOOP(WASM_BR(1))), WASM_GET_LOCAL(0));
FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
}
WASM_EXEC_TEST(Loop_empty_brif1) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
BUILD(r, B1(WASM_LOOP(WASM_BR_IF(1, WASM_ZERO))), WASM_GET_LOCAL(0));
FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); }
}
WASM_EXEC_TEST(Loop_empty_brif2) {
- WasmRunner<uint32_t> r(execution_mode, MachineType::Uint32(),
- MachineType::Uint32());
+ WasmRunner<uint32_t, uint32_t, uint32_t> r(execution_mode);
BUILD(r, WASM_LOOP_I(WASM_BRV_IF(1, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))));
FOR_UINT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i, *i + 1)); }
}
WASM_EXEC_TEST(Loop_empty_brif3) {
- WasmRunner<uint32_t> r(execution_mode, MachineType::Uint32(),
- MachineType::Uint32(), MachineType::Uint32());
+ WasmRunner<uint32_t, uint32_t, uint32_t, uint32_t> r(execution_mode);
BUILD(r, WASM_LOOP(WASM_BRV_IFD(1, WASM_GET_LOCAL(2), WASM_GET_LOCAL(0))),
WASM_GET_LOCAL(1));
FOR_UINT32_INPUTS(i) {
@@ -1307,9 +1247,9 @@ WASM_EXEC_TEST(Loop_empty_brif3) {
}
WASM_EXEC_TEST(Block_BrIf_P) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
- BUILD(r, WASM_BLOCK_I(WASM_BRV_IFD(0, WASM_I8(51), WASM_GET_LOCAL(0)),
- WASM_I8(52)));
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ BUILD(r, WASM_BLOCK_I(WASM_BRV_IFD(0, WASM_I32V_1(51), WASM_GET_LOCAL(0)),
+ WASM_I32V_1(52)));
FOR_INT32_INPUTS(i) {
int32_t expected = *i ? 51 : 52;
CHECK_EQ(expected, r.Call(*i));
@@ -1317,12 +1257,12 @@ WASM_EXEC_TEST(Block_BrIf_P) {
}
WASM_EXEC_TEST(Block_IfElse_P_assign) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
// { if (p0) p0 = 71; else p0 = 72; return p0; }
- BUILD(r, // --
- WASM_IF_ELSE(WASM_GET_LOCAL(0), // --
- WASM_SET_LOCAL(0, WASM_I8(71)), // --
- WASM_SET_LOCAL(0, WASM_I8(72))), // --
+ BUILD(r, // --
+ WASM_IF_ELSE(WASM_GET_LOCAL(0), // --
+ WASM_SET_LOCAL(0, WASM_I32V_2(71)), // --
+ WASM_SET_LOCAL(0, WASM_I32V_2(72))), // --
WASM_GET_LOCAL(0));
FOR_INT32_INPUTS(i) {
int32_t expected = *i ? 71 : 72;
@@ -1331,12 +1271,13 @@ WASM_EXEC_TEST(Block_IfElse_P_assign) {
}
WASM_EXEC_TEST(Block_IfElse_P_return) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
// if (p0) return 81; else return 82;
BUILD(r, // --
WASM_IF_ELSE(WASM_GET_LOCAL(0), // --
RET_I8(81), // --
- RET_I8(82))); // --
+ RET_I8(82)), // --
+ WASM_ZERO); // --
FOR_INT32_INPUTS(i) {
int32_t expected = *i ? 81 : 82;
CHECK_EQ(expected, r.Call(*i));
@@ -1344,9 +1285,9 @@ WASM_EXEC_TEST(Block_IfElse_P_return) {
}
WASM_EXEC_TEST(Block_If_P_assign) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
// { if (p0) p0 = 61; p0; }
- BUILD(r, WASM_IF(WASM_GET_LOCAL(0), WASM_SET_LOCAL(0, WASM_I8(61))),
+ BUILD(r, WASM_IF(WASM_GET_LOCAL(0), WASM_SET_LOCAL(0, WASM_I32V_1(61))),
WASM_GET_LOCAL(0));
FOR_INT32_INPUTS(i) {
int32_t expected = *i ? 61 : *i;
@@ -1355,18 +1296,18 @@ WASM_EXEC_TEST(Block_If_P_assign) {
}
WASM_EXEC_TEST(DanglingAssign) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
// { return 0; p0 = 0; }
- BUILD(r, B2(RET_I8(99), WASM_SET_LOCAL(0, WASM_ZERO)));
+ BUILD(r, WASM_BLOCK_I(RET_I8(99), WASM_TEE_LOCAL(0, WASM_ZERO)));
CHECK_EQ(99, r.Call(1));
}
WASM_EXEC_TEST(ExprIf_P) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
// p0 ? 11 : 22;
BUILD(r, WASM_IF_ELSE_I(WASM_GET_LOCAL(0), // --
- WASM_I8(11), // --
- WASM_I8(22))); // --
+ WASM_I32V_1(11), // --
+ WASM_I32V_1(22))); // --
FOR_INT32_INPUTS(i) {
int32_t expected = *i ? 11 : 22;
CHECK_EQ(expected, r.Call(*i));
@@ -1374,11 +1315,11 @@ WASM_EXEC_TEST(ExprIf_P) {
}
WASM_EXEC_TEST(CountDown) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
- BUILD(r, WASM_LOOP(WASM_IFB(
- WASM_GET_LOCAL(0),
- WASM_SET_LOCAL(0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(1))),
- WASM_BR(1))),
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ BUILD(r, WASM_LOOP(WASM_IFB(WASM_GET_LOCAL(0),
+ WASM_SET_LOCAL(0, WASM_I32_SUB(WASM_GET_LOCAL(0),
+ WASM_I32V_1(1))),
+ WASM_BR(1))),
WASM_GET_LOCAL(0));
CHECK_EQ(0, r.Call(1));
CHECK_EQ(0, r.Call(10));
@@ -1386,23 +1327,24 @@ WASM_EXEC_TEST(CountDown) {
}
WASM_EXEC_TEST(CountDown_fallthru) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
- BUILD(r, WASM_LOOP(
- WASM_IF(WASM_NOT(WASM_GET_LOCAL(0)),
- WASM_BRV(2, WASM_GET_LOCAL(0))),
- WASM_SET_LOCAL(0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(1))),
- WASM_CONTINUE(0)),
- WASM_GET_LOCAL(0));
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ BUILD(
+ r,
+ WASM_LOOP(
+ WASM_IF(WASM_NOT(WASM_GET_LOCAL(0)), WASM_BRV(2, WASM_GET_LOCAL(0))),
+ WASM_SET_LOCAL(0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I32V_1(1))),
+ WASM_CONTINUE(0)),
+ WASM_GET_LOCAL(0));
CHECK_EQ(0, r.Call(1));
CHECK_EQ(0, r.Call(10));
CHECK_EQ(0, r.Call(100));
}
WASM_EXEC_TEST(WhileCountDown) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
- BUILD(r, WASM_WHILE(
- WASM_GET_LOCAL(0),
- WASM_SET_LOCAL(0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(1)))),
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ BUILD(r, WASM_WHILE(WASM_GET_LOCAL(0),
+ WASM_SET_LOCAL(
+ 0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I32V_1(1)))),
WASM_GET_LOCAL(0));
CHECK_EQ(0, r.Call(1));
CHECK_EQ(0, r.Call(10));
@@ -1410,10 +1352,9 @@ WASM_EXEC_TEST(WhileCountDown) {
}
WASM_EXEC_TEST(Loop_if_break1) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32(),
- MachineType::Int32());
+ WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
BUILD(r, WASM_LOOP(WASM_IF(WASM_GET_LOCAL(0), WASM_BRV(2, WASM_GET_LOCAL(1))),
- WASM_SET_LOCAL(0, WASM_I8(99))),
+ WASM_SET_LOCAL(0, WASM_I32V_2(99))),
WASM_GET_LOCAL(0));
CHECK_EQ(99, r.Call(0, 11));
CHECK_EQ(65, r.Call(3, 65));
@@ -1422,10 +1363,9 @@ WASM_EXEC_TEST(Loop_if_break1) {
}
WASM_EXEC_TEST(Loop_if_break2) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32(),
- MachineType::Int32());
+ WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
BUILD(r, WASM_LOOP(WASM_BRV_IF(1, WASM_GET_LOCAL(1), WASM_GET_LOCAL(0)),
- WASM_DROP, WASM_SET_LOCAL(0, WASM_I8(99))),
+ WASM_DROP, WASM_SET_LOCAL(0, WASM_I32V_2(99))),
WASM_GET_LOCAL(0));
CHECK_EQ(99, r.Call(0, 33));
CHECK_EQ(3, r.Call(1, 3));
@@ -1434,9 +1374,9 @@ WASM_EXEC_TEST(Loop_if_break2) {
}
WASM_EXEC_TEST(Loop_if_break_fallthru) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
BUILD(r, B1(WASM_LOOP(WASM_IF(WASM_GET_LOCAL(0), WASM_BR(2)),
- WASM_SET_LOCAL(0, WASM_I8(93)))),
+ WASM_SET_LOCAL(0, WASM_I32V_2(93)))),
WASM_GET_LOCAL(0));
CHECK_EQ(93, r.Call(0));
CHECK_EQ(3, r.Call(3));
@@ -1445,9 +1385,9 @@ WASM_EXEC_TEST(Loop_if_break_fallthru) {
}
WASM_EXEC_TEST(Loop_if_break_fallthru2) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
BUILD(r, B1(B1(WASM_LOOP(WASM_IF(WASM_GET_LOCAL(0), WASM_BR(2)),
- WASM_SET_LOCAL(0, WASM_I8(93))))),
+ WASM_SET_LOCAL(0, WASM_I32V_2(93))))),
WASM_GET_LOCAL(0));
CHECK_EQ(93, r.Call(0));
CHECK_EQ(3, r.Call(3));
@@ -1456,71 +1396,68 @@ WASM_EXEC_TEST(Loop_if_break_fallthru2) {
}
WASM_EXEC_TEST(IfBreak1) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
BUILD(r, WASM_IF(WASM_GET_LOCAL(0), WASM_SEQ(WASM_BR(0), WASM_UNREACHABLE)),
- WASM_I8(91));
+ WASM_I32V_2(91));
CHECK_EQ(91, r.Call(0));
CHECK_EQ(91, r.Call(1));
CHECK_EQ(91, r.Call(-8734));
}
WASM_EXEC_TEST(IfBreak2) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
BUILD(r, WASM_IF(WASM_GET_LOCAL(0), WASM_SEQ(WASM_BR(0), RET_I8(77))),
- WASM_I8(81));
+ WASM_I32V_2(81));
CHECK_EQ(81, r.Call(0));
CHECK_EQ(81, r.Call(1));
CHECK_EQ(81, r.Call(-8734));
}
WASM_EXEC_TEST(LoadMemI32) {
- TestingModule module(execution_mode);
- int32_t* memory = module.AddMemoryElems<int32_t>(8);
- WasmRunner<int32_t> r(&module, MachineType::Int32());
- module.RandomizeMemory(1111);
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ int32_t* memory = r.module().AddMemoryElems<int32_t>(8);
+ r.module().RandomizeMemory(1111);
- BUILD(r, WASM_LOAD_MEM(MachineType::Int32(), WASM_I8(0)));
+ BUILD(r, WASM_LOAD_MEM(MachineType::Int32(), WASM_ZERO));
- module.WriteMemory(&memory[0], 99999999);
+ r.module().WriteMemory(&memory[0], 99999999);
CHECK_EQ(99999999, r.Call(0));
- module.WriteMemory(&memory[0], 88888888);
+ r.module().WriteMemory(&memory[0], 88888888);
CHECK_EQ(88888888, r.Call(0));
- module.WriteMemory(&memory[0], 77777777);
+ r.module().WriteMemory(&memory[0], 77777777);
CHECK_EQ(77777777, r.Call(0));
}
WASM_EXEC_TEST(LoadMemI32_alignment) {
- TestingModule module(execution_mode);
- int32_t* memory = module.AddMemoryElems<int32_t>(8);
for (byte alignment = 0; alignment <= 2; ++alignment) {
- WasmRunner<int32_t> r(&module, MachineType::Int32());
- module.RandomizeMemory(1111);
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ int32_t* memory = r.module().AddMemoryElems<int32_t>(8);
+ r.module().RandomizeMemory(1111);
BUILD(r,
- WASM_LOAD_MEM_ALIGNMENT(MachineType::Int32(), WASM_I8(0), alignment));
+ WASM_LOAD_MEM_ALIGNMENT(MachineType::Int32(), WASM_ZERO, alignment));
- module.WriteMemory(&memory[0], 0x1a2b3c4d);
+ r.module().WriteMemory(&memory[0], 0x1a2b3c4d);
CHECK_EQ(0x1a2b3c4d, r.Call(0));
- module.WriteMemory(&memory[0], 0x5e6f7a8b);
+ r.module().WriteMemory(&memory[0], 0x5e6f7a8b);
CHECK_EQ(0x5e6f7a8b, r.Call(0));
- module.WriteMemory(&memory[0], 0x7ca0b1c2);
+ r.module().WriteMemory(&memory[0], 0x7ca0b1c2);
CHECK_EQ(0x7ca0b1c2, r.Call(0));
}
}
-WASM_EXEC_TEST(LoadMemI32_oob) {
- TestingModule module(execution_mode);
- int32_t* memory = module.AddMemoryElems<int32_t>(8);
- WasmRunner<int32_t> r(&module, MachineType::Uint32());
- module.RandomizeMemory(1111);
+WASM_EXEC_TEST_WITH_TRAP(LoadMemI32_oob) {
+ WasmRunner<int32_t, uint32_t> r(execution_mode);
+ int32_t* memory = r.module().AddMemoryElems<int32_t>(8);
+ r.module().RandomizeMemory(1111);
BUILD(r, WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(0)));
- module.WriteMemory(&memory[0], 88888888);
+ r.module().WriteMemory(&memory[0], 88888888);
CHECK_EQ(88888888, r.Call(0u));
for (uint32_t offset = 29; offset < 40; ++offset) {
CHECK_TRAP(r.Call(offset));
@@ -1531,10 +1468,7 @@ WASM_EXEC_TEST(LoadMemI32_oob) {
}
}
-WASM_EXEC_TEST(LoadMem_offset_oob) {
- TestingModule module(execution_mode);
- module.AddMemoryElems<int32_t>(8);
-
+WASM_EXEC_TEST_WITH_TRAP(LoadMem_offset_oob) {
static const MachineType machineTypes[] = {
MachineType::Int8(), MachineType::Uint8(), MachineType::Int16(),
MachineType::Uint16(), MachineType::Int32(), MachineType::Uint32(),
@@ -1542,8 +1476,10 @@ WASM_EXEC_TEST(LoadMem_offset_oob) {
MachineType::Float64()};
for (size_t m = 0; m < arraysize(machineTypes); ++m) {
- module.RandomizeMemory(1116 + static_cast<int>(m));
- WasmRunner<int32_t> r(&module, MachineType::Uint32());
+ WasmRunner<int32_t, uint32_t> r(execution_mode);
+ r.module().AddMemoryElems<int32_t>(8);
+ r.module().RandomizeMemory(1116 + static_cast<int>(m));
+
uint32_t boundary = 24 - WasmOpcodes::MemSize(machineTypes[m]);
BUILD(r, WASM_LOAD_MEM_OFFSET(machineTypes[m], 8, WASM_GET_LOCAL(0)),
@@ -1558,46 +1494,43 @@ WASM_EXEC_TEST(LoadMem_offset_oob) {
}
WASM_EXEC_TEST(LoadMemI32_offset) {
- TestingModule module(execution_mode);
- int32_t* memory = module.AddMemoryElems<int32_t>(4);
- WasmRunner<int32_t> r(&module, MachineType::Int32());
- module.RandomizeMemory(1111);
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ int32_t* memory = r.module().AddMemoryElems<int32_t>(4);
+ r.module().RandomizeMemory(1111);
BUILD(r, WASM_LOAD_MEM_OFFSET(MachineType::Int32(), 4, WASM_GET_LOCAL(0)));
- module.WriteMemory(&memory[0], 66666666);
- module.WriteMemory(&memory[1], 77777777);
- module.WriteMemory(&memory[2], 88888888);
- module.WriteMemory(&memory[3], 99999999);
+ r.module().WriteMemory(&memory[0], 66666666);
+ r.module().WriteMemory(&memory[1], 77777777);
+ r.module().WriteMemory(&memory[2], 88888888);
+ r.module().WriteMemory(&memory[3], 99999999);
CHECK_EQ(77777777, r.Call(0));
CHECK_EQ(88888888, r.Call(4));
CHECK_EQ(99999999, r.Call(8));
- module.WriteMemory(&memory[0], 11111111);
- module.WriteMemory(&memory[1], 22222222);
- module.WriteMemory(&memory[2], 33333333);
- module.WriteMemory(&memory[3], 44444444);
+ r.module().WriteMemory(&memory[0], 11111111);
+ r.module().WriteMemory(&memory[1], 22222222);
+ r.module().WriteMemory(&memory[2], 33333333);
+ r.module().WriteMemory(&memory[3], 44444444);
CHECK_EQ(22222222, r.Call(0));
CHECK_EQ(33333333, r.Call(4));
CHECK_EQ(44444444, r.Call(8));
}
-WASM_EXEC_TEST(LoadMemI32_const_oob_misaligned) {
+WASM_EXEC_TEST_WITH_TRAP(LoadMemI32_const_oob_misaligned) {
const int kMemSize = 12;
// TODO(titzer): Fix misaligned accesses on MIPS and re-enable.
for (int offset = 0; offset < kMemSize + 5; ++offset) {
for (int index = 0; index < kMemSize + 5; ++index) {
- TestingModule module(execution_mode);
- module.AddMemoryElems<byte>(kMemSize);
-
- WasmRunner<int32_t> r(&module);
- module.RandomizeMemory();
+ WasmRunner<int32_t> r(execution_mode);
+ r.module().AddMemoryElems<byte>(kMemSize);
+ r.module().RandomizeMemory();
- BUILD(r,
- WASM_LOAD_MEM_OFFSET(MachineType::Int32(), offset, WASM_I8(index)));
+ BUILD(r, WASM_LOAD_MEM_OFFSET(MachineType::Int32(), offset,
+ WASM_I32V_2(index)));
if ((offset + index) <= static_cast<int>((kMemSize - sizeof(int32_t)))) {
- CHECK_EQ(module.raw_val_at<int32_t>(offset + index), r.Call());
+ CHECK_EQ(r.module().raw_val_at<int32_t>(offset + index), r.Call());
} else {
CHECK_TRAP(r.Call());
}
@@ -1605,21 +1538,19 @@ WASM_EXEC_TEST(LoadMemI32_const_oob_misaligned) {
}
}
-WASM_EXEC_TEST(LoadMemI32_const_oob) {
+WASM_EXEC_TEST_WITH_TRAP(LoadMemI32_const_oob) {
const int kMemSize = 24;
for (int offset = 0; offset < kMemSize + 5; offset += 4) {
for (int index = 0; index < kMemSize + 5; index += 4) {
- TestingModule module(execution_mode);
- module.AddMemoryElems<byte>(kMemSize);
-
- WasmRunner<int32_t> r(&module);
- module.RandomizeMemory();
+ WasmRunner<int32_t> r(execution_mode);
+ r.module().AddMemoryElems<byte>(kMemSize);
+ r.module().RandomizeMemory();
- BUILD(r,
- WASM_LOAD_MEM_OFFSET(MachineType::Int32(), offset, WASM_I8(index)));
+ BUILD(r, WASM_LOAD_MEM_OFFSET(MachineType::Int32(), offset,
+ WASM_I32V_2(index)));
if ((offset + index) <= static_cast<int>((kMemSize - sizeof(int32_t)))) {
- CHECK_EQ(module.raw_val_at<int32_t>(offset + index), r.Call());
+ CHECK_EQ(r.module().raw_val_at<int32_t>(offset + index), r.Call());
} else {
CHECK_TRAP(r.Call());
}
@@ -1628,27 +1559,25 @@ WASM_EXEC_TEST(LoadMemI32_const_oob) {
}
WASM_EXEC_TEST(StoreMemI32_alignment) {
- TestingModule module(execution_mode);
- int32_t* memory = module.AddMemoryElems<int32_t>(4);
const int32_t kWritten = 0x12345678;
for (byte i = 0; i <= 2; ++i) {
- WasmRunner<int32_t> r(&module, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ int32_t* memory = r.module().AddMemoryElems<int32_t>(4);
BUILD(r, WASM_STORE_MEM_ALIGNMENT(MachineType::Int32(), WASM_ZERO, i,
WASM_GET_LOCAL(0)),
WASM_GET_LOCAL(0));
- module.RandomizeMemory(1111);
+ r.module().RandomizeMemory(1111);
memory[0] = 0;
CHECK_EQ(kWritten, r.Call(kWritten));
- CHECK_EQ(kWritten, module.ReadMemory(&memory[0]));
+ CHECK_EQ(kWritten, r.module().ReadMemory(&memory[0]));
}
}
WASM_EXEC_TEST(StoreMemI32_offset) {
- TestingModule module(execution_mode);
- int32_t* memory = module.AddMemoryElems<int32_t>(4);
- WasmRunner<int32_t> r(&module, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ int32_t* memory = r.module().AddMemoryElems<int32_t>(4);
const int32_t kWritten = 0xaabbccdd;
BUILD(r, WASM_STORE_MEM_OFFSET(MachineType::Int32(), 4, WASM_GET_LOCAL(0),
@@ -1656,23 +1585,20 @@ WASM_EXEC_TEST(StoreMemI32_offset) {
WASM_I32V_5(kWritten));
for (int i = 0; i < 2; ++i) {
- module.RandomizeMemory(1111);
- module.WriteMemory(&memory[0], 66666666);
- module.WriteMemory(&memory[1], 77777777);
- module.WriteMemory(&memory[2], 88888888);
- module.WriteMemory(&memory[3], 99999999);
+ r.module().RandomizeMemory(1111);
+ r.module().WriteMemory(&memory[0], 66666666);
+ r.module().WriteMemory(&memory[1], 77777777);
+ r.module().WriteMemory(&memory[2], 88888888);
+ r.module().WriteMemory(&memory[3], 99999999);
CHECK_EQ(kWritten, r.Call(i * 4));
- CHECK_EQ(66666666, module.ReadMemory(&memory[0]));
- CHECK_EQ(i == 0 ? kWritten : 77777777, module.ReadMemory(&memory[1]));
- CHECK_EQ(i == 1 ? kWritten : 88888888, module.ReadMemory(&memory[2]));
- CHECK_EQ(i == 2 ? kWritten : 99999999, module.ReadMemory(&memory[3]));
+ CHECK_EQ(66666666, r.module().ReadMemory(&memory[0]));
+ CHECK_EQ(i == 0 ? kWritten : 77777777, r.module().ReadMemory(&memory[1]));
+ CHECK_EQ(i == 1 ? kWritten : 88888888, r.module().ReadMemory(&memory[2]));
+ CHECK_EQ(i == 2 ? kWritten : 99999999, r.module().ReadMemory(&memory[3]));
}
}
-WASM_EXEC_TEST(StoreMem_offset_oob) {
- TestingModule module(execution_mode);
- byte* memory = module.AddMemoryElems<byte>(32);
-
+WASM_EXEC_TEST_WITH_TRAP(StoreMem_offset_oob) {
// 64-bit cases are handled in test-run-wasm-64.cc
static const MachineType machineTypes[] = {
MachineType::Int8(), MachineType::Uint8(), MachineType::Int16(),
@@ -1680,8 +1606,10 @@ WASM_EXEC_TEST(StoreMem_offset_oob) {
MachineType::Float32(), MachineType::Float64()};
for (size_t m = 0; m < arraysize(machineTypes); ++m) {
- module.RandomizeMemory(1119 + static_cast<int>(m));
- WasmRunner<int32_t> r(&module, MachineType::Uint32());
+ WasmRunner<int32_t, uint32_t> r(execution_mode);
+ byte* memory = r.module().AddMemoryElems<byte>(32);
+
+ r.module().RandomizeMemory(1119 + static_cast<int>(m));
BUILD(r, WASM_STORE_MEM_OFFSET(machineTypes[m], 8, WASM_GET_LOCAL(0),
WASM_LOAD_MEM(machineTypes[m], WASM_ZERO)),
@@ -1700,43 +1628,40 @@ WASM_EXEC_TEST(StoreMem_offset_oob) {
WASM_EXEC_TEST(LoadMemI32_P) {
const int kNumElems = 8;
- TestingModule module(execution_mode);
- int32_t* memory = module.AddMemoryElems<int32_t>(kNumElems);
- WasmRunner<int32_t> r(&module, MachineType::Int32());
- module.RandomizeMemory(2222);
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ int32_t* memory = r.module().AddMemoryElems<int32_t>(kNumElems);
+ r.module().RandomizeMemory(2222);
BUILD(r, WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(0)));
for (int i = 0; i < kNumElems; ++i) {
- CHECK_EQ(module.ReadMemory(&memory[i]), r.Call(i * 4));
+ CHECK_EQ(r.module().ReadMemory(&memory[i]), r.Call(i * 4));
}
}
WASM_EXEC_TEST(MemI32_Sum) {
const int kNumElems = 20;
- TestingModule module(execution_mode);
- uint32_t* memory = module.AddMemoryElems<uint32_t>(kNumElems);
- WasmRunner<uint32_t> r(&module, MachineType::Int32());
- const byte kSum = r.AllocateLocal(kAstI32);
+ WasmRunner<uint32_t, int32_t> r(execution_mode);
+ uint32_t* memory = r.module().AddMemoryElems<uint32_t>(kNumElems);
+ const byte kSum = r.AllocateLocal(kWasmI32);
- BUILD(
- r,
- WASM_WHILE(
- WASM_GET_LOCAL(0),
- WASM_BLOCK(
- WASM_SET_LOCAL(kSum,
- WASM_I32_ADD(WASM_GET_LOCAL(kSum),
+ BUILD(r, WASM_WHILE(
+ WASM_GET_LOCAL(0),
+ WASM_BLOCK(
+ WASM_SET_LOCAL(
+ kSum, WASM_I32_ADD(WASM_GET_LOCAL(kSum),
WASM_LOAD_MEM(MachineType::Int32(),
WASM_GET_LOCAL(0)))),
- WASM_SET_LOCAL(0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(4))))),
- WASM_GET_LOCAL(1));
+ WASM_SET_LOCAL(
+ 0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I32V_1(4))))),
+ WASM_GET_LOCAL(1));
// Run 4 trials.
for (int i = 0; i < 3; ++i) {
- module.RandomizeMemory(i * 33);
+ r.module().RandomizeMemory(i * 33);
uint32_t expected = 0;
for (size_t j = kNumElems - 1; j > 0; --j) {
- expected += module.ReadMemory(&memory[j]);
+ expected += r.module().ReadMemory(&memory[j]);
}
uint32_t result = r.Call(4 * (kNumElems - 1));
CHECK_EQ(expected, result);
@@ -1745,9 +1670,8 @@ WASM_EXEC_TEST(MemI32_Sum) {
WASM_EXEC_TEST(CheckMachIntsZero) {
const int kNumElems = 55;
- TestingModule module(execution_mode);
- module.AddMemoryElems<uint32_t>(kNumElems);
- WasmRunner<uint32_t> r(&module, MachineType::Int32());
+ WasmRunner<uint32_t, int32_t> r(execution_mode);
+ r.module().AddMemoryElems<uint32_t>(kNumElems);
BUILD(r, // --
/**/ kExprLoop, kLocalVoid, // --
@@ -1756,78 +1680,76 @@ WASM_EXEC_TEST(CheckMachIntsZero) {
/* */ kExprGetLocal, 0, // --
/* */ kExprI32LoadMem, 0, 0, // --
/* */ kExprIf, kLocalVoid, // --
- /* */ kExprI8Const, 255, // --
+ /* */ kExprI32Const, 127, // --
/* */ kExprReturn, // --
/* */ kExprEnd, // --
/* */ kExprGetLocal, 0, // --
- /* */ kExprI8Const, 4, // --
+ /* */ kExprI32Const, 4, // --
/* */ kExprI32Sub, // --
/* */ kExprTeeLocal, 0, // --
/* */ kExprBr, DEPTH_0, // --
/* */ kExprEnd, // --
/**/ kExprEnd, // --
- /**/ kExprI8Const, 0); // --
+ /**/ kExprI32Const, 0); // --
- module.BlankMemory();
- CHECK_EQ(0u, r.Call((kNumElems - 1) * 4));
+ r.module().BlankMemory();
+ CHECK_EQ(0, r.Call((kNumElems - 1) * 4));
}
WASM_EXEC_TEST(MemF32_Sum) {
const int kSize = 5;
- TestingModule module(execution_mode);
- module.AddMemoryElems<float>(kSize);
- float* buffer = module.raw_mem_start<float>();
- module.WriteMemory(&buffer[0], -99.25f);
- module.WriteMemory(&buffer[1], -888.25f);
- module.WriteMemory(&buffer[2], -77.25f);
- module.WriteMemory(&buffer[3], 66666.25f);
- module.WriteMemory(&buffer[4], 5555.25f);
- WasmRunner<int32_t> r(&module, MachineType::Int32());
- const byte kSum = r.AllocateLocal(kAstF32);
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ r.module().AddMemoryElems<float>(kSize);
+ float* buffer = r.module().raw_mem_start<float>();
+ r.module().WriteMemory(&buffer[0], -99.25f);
+ r.module().WriteMemory(&buffer[1], -888.25f);
+ r.module().WriteMemory(&buffer[2], -77.25f);
+ r.module().WriteMemory(&buffer[3], 66666.25f);
+ r.module().WriteMemory(&buffer[4], 5555.25f);
+ const byte kSum = r.AllocateLocal(kWasmF32);
- BUILD(
- r,
- WASM_WHILE(
- WASM_GET_LOCAL(0),
- WASM_BLOCK(
- WASM_SET_LOCAL(kSum,
- WASM_F32_ADD(WASM_GET_LOCAL(kSum),
+ BUILD(r, WASM_WHILE(
+ WASM_GET_LOCAL(0),
+ WASM_BLOCK(
+ WASM_SET_LOCAL(
+ kSum, WASM_F32_ADD(WASM_GET_LOCAL(kSum),
WASM_LOAD_MEM(MachineType::Float32(),
WASM_GET_LOCAL(0)))),
- WASM_SET_LOCAL(0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(4))))),
- WASM_STORE_MEM(MachineType::Float32(), WASM_ZERO, WASM_GET_LOCAL(kSum)),
- WASM_GET_LOCAL(0));
+ WASM_SET_LOCAL(
+ 0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I32V_1(4))))),
+ WASM_STORE_MEM(MachineType::Float32(), WASM_ZERO, WASM_GET_LOCAL(kSum)),
+ WASM_GET_LOCAL(0));
CHECK_EQ(0, r.Call(4 * (kSize - 1)));
- CHECK_NE(-99.25f, module.ReadMemory(&buffer[0]));
- CHECK_EQ(71256.0f, module.ReadMemory(&buffer[0]));
+ CHECK_NE(-99.25f, r.module().ReadMemory(&buffer[0]));
+ CHECK_EQ(71256.0f, r.module().ReadMemory(&buffer[0]));
}
template <typename T>
T GenerateAndRunFold(WasmExecutionMode execution_mode, WasmOpcode binop,
- T* buffer, uint32_t size, LocalType astType,
+ T* buffer, uint32_t size, ValueType astType,
MachineType memType) {
- TestingModule module(execution_mode);
- T* memory = module.AddMemoryElems<T>(size);
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ T* memory = r.module().AddMemoryElems<T>(size);
for (uint32_t i = 0; i < size; ++i) {
- module.WriteMemory(&memory[i], buffer[i]);
+ r.module().WriteMemory(&memory[i], buffer[i]);
}
- WasmRunner<int32_t> r(&module, MachineType::Int32());
const byte kAccum = r.AllocateLocal(astType);
- BUILD(r, WASM_SET_LOCAL(kAccum, WASM_LOAD_MEM(memType, WASM_ZERO)),
- WASM_WHILE(
- WASM_GET_LOCAL(0),
- WASM_BLOCK(WASM_SET_LOCAL(
- kAccum, WASM_BINOP(binop, WASM_GET_LOCAL(kAccum),
- WASM_LOAD_MEM(
- memType, WASM_GET_LOCAL(0)))),
- WASM_SET_LOCAL(0, WASM_I32_SUB(WASM_GET_LOCAL(0),
- WASM_I8(sizeof(T)))))),
- WASM_STORE_MEM(memType, WASM_ZERO, WASM_GET_LOCAL(kAccum)),
- WASM_GET_LOCAL(0));
+ BUILD(
+ r, WASM_SET_LOCAL(kAccum, WASM_LOAD_MEM(memType, WASM_ZERO)),
+ WASM_WHILE(
+ WASM_GET_LOCAL(0),
+ WASM_BLOCK(WASM_SET_LOCAL(
+ kAccum,
+ WASM_BINOP(binop, WASM_GET_LOCAL(kAccum),
+ WASM_LOAD_MEM(memType, WASM_GET_LOCAL(0)))),
+ WASM_SET_LOCAL(0, WASM_I32_SUB(WASM_GET_LOCAL(0),
+ WASM_I32V_1(sizeof(T)))))),
+ WASM_STORE_MEM(memType, WASM_ZERO, WASM_GET_LOCAL(kAccum)),
+ WASM_GET_LOCAL(0));
r.Call(static_cast<int>(sizeof(T) * (size - 1)));
- return module.ReadMemory(&memory[0]);
+ return r.module().ReadMemory(&memory[0]);
}
WASM_EXEC_TEST(MemF64_Mul) {
@@ -1835,20 +1757,19 @@ WASM_EXEC_TEST(MemF64_Mul) {
double buffer[kSize] = {1, 2, 2, 2, 2, 2};
double result =
GenerateAndRunFold<double>(execution_mode, kExprF64Mul, buffer, kSize,
- kAstF64, MachineType::Float64());
+ kWasmF64, MachineType::Float64());
CHECK_EQ(32, result);
}
WASM_EXEC_TEST(Build_Wasm_Infinite_Loop) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
// Only build the graph and compile, don't run.
- BUILD(r, WASM_INFINITE_LOOP);
+ BUILD(r, WASM_INFINITE_LOOP, WASM_ZERO);
}
WASM_EXEC_TEST(Build_Wasm_Infinite_Loop_effect) {
- TestingModule module(execution_mode);
- module.AddMemoryElems<int8_t>(16);
- WasmRunner<int32_t> r(&module, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ r.module().AddMemoryElems<int8_t>(16);
// Only build the graph and compile, don't run.
BUILD(r, WASM_LOOP(WASM_LOAD_MEM(MachineType::Int32(), WASM_ZERO), WASM_DROP),
@@ -1856,72 +1777,83 @@ WASM_EXEC_TEST(Build_Wasm_Infinite_Loop_effect) {
}
WASM_EXEC_TEST(Unreachable0a) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
- BUILD(r, WASM_BLOCK_I(WASM_BRV(0, WASM_I8(9)), RET(WASM_GET_LOCAL(0))));
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ BUILD(r, WASM_BLOCK_I(WASM_BRV(0, WASM_I32V_1(9)), RET(WASM_GET_LOCAL(0))));
CHECK_EQ(9, r.Call(0));
CHECK_EQ(9, r.Call(1));
}
WASM_EXEC_TEST(Unreachable0b) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
- BUILD(r, WASM_BLOCK_I(WASM_BRV(0, WASM_I8(7)), WASM_UNREACHABLE));
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ BUILD(r, WASM_BLOCK_I(WASM_BRV(0, WASM_I32V_1(7)), WASM_UNREACHABLE));
CHECK_EQ(7, r.Call(0));
CHECK_EQ(7, r.Call(1));
}
TEST(Build_Wasm_Unreachable1) {
- WasmRunner<int32_t> r(kExecuteCompiled, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(kExecuteCompiled);
BUILD(r, WASM_UNREACHABLE);
}
TEST(Build_Wasm_Unreachable2) {
- WasmRunner<int32_t> r(kExecuteCompiled, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(kExecuteCompiled);
BUILD(r, WASM_UNREACHABLE, WASM_UNREACHABLE);
}
TEST(Build_Wasm_Unreachable3) {
- WasmRunner<int32_t> r(kExecuteCompiled, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(kExecuteCompiled);
BUILD(r, WASM_UNREACHABLE, WASM_UNREACHABLE, WASM_UNREACHABLE);
}
TEST(Build_Wasm_UnreachableIf1) {
- WasmRunner<int32_t> r(kExecuteCompiled, MachineType::Int32());
- BUILD(r, WASM_UNREACHABLE, WASM_IF(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0)));
+ WasmRunner<int32_t, int32_t> r(kExecuteCompiled);
+ BUILD(r, WASM_UNREACHABLE,
+ WASM_IF(WASM_GET_LOCAL(0), WASM_SEQ(WASM_GET_LOCAL(0), WASM_DROP)),
+ WASM_ZERO);
}
TEST(Build_Wasm_UnreachableIf2) {
- WasmRunner<int32_t> r(kExecuteCompiled, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(kExecuteCompiled);
BUILD(r, WASM_UNREACHABLE,
- WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0), WASM_UNREACHABLE));
+ WASM_IF_ELSE_I(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0), WASM_UNREACHABLE));
}
WASM_EXEC_TEST(Unreachable_Load) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ r.module().AddMemory(8);
BUILD(r, WASM_BLOCK_I(WASM_BRV(0, WASM_GET_LOCAL(0)),
WASM_LOAD_MEM(MachineType::Int8(), WASM_GET_LOCAL(0))));
CHECK_EQ(11, r.Call(11));
CHECK_EQ(21, r.Call(21));
}
+WASM_EXEC_TEST(BrV_Fallthrough) {
+ WasmRunner<int32_t> r(execution_mode);
+ BUILD(r, WASM_BLOCK_I(WASM_BLOCK(WASM_BRV(1, WASM_I32V_1(42))),
+ WASM_I32V_1(22)));
+ CHECK_EQ(42, r.Call());
+}
+
WASM_EXEC_TEST(Infinite_Loop_not_taken1) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
- BUILD(r, WASM_IF(WASM_GET_LOCAL(0), WASM_INFINITE_LOOP), WASM_I8(45));
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ BUILD(r, WASM_IF(WASM_GET_LOCAL(0), WASM_INFINITE_LOOP), WASM_I32V_1(45));
// Run the code, but don't go into the infinite loop.
CHECK_EQ(45, r.Call(0));
}
WASM_EXEC_TEST(Infinite_Loop_not_taken2) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
- BUILD(r,
- WASM_BLOCK_I(WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_BRV(1, WASM_I8(45)),
- WASM_INFINITE_LOOP)));
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ BUILD(r, WASM_BLOCK_I(
+ WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_BRV(1, WASM_I32V_1(45)),
+ WASM_INFINITE_LOOP),
+ WASM_ZERO));
// Run the code, but don't go into the infinite loop.
CHECK_EQ(45, r.Call(1));
}
WASM_EXEC_TEST(Infinite_Loop_not_taken2_brif) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
- BUILD(r, WASM_BLOCK_I(WASM_BRV_IF(0, WASM_I8(45), WASM_GET_LOCAL(0)),
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ BUILD(r, WASM_BLOCK_I(WASM_BRV_IF(0, WASM_I32V_1(45), WASM_GET_LOCAL(0)),
WASM_INFINITE_LOOP));
// Run the code, but don't go into the infinite loop.
CHECK_EQ(45, r.Call(1));
@@ -1940,13 +1872,19 @@ static void TestBuildGraphForSimpleExpression(WasmOpcode opcode) {
FunctionSig* sig = WasmOpcodes::Signature(opcode);
if (sig->parameter_count() == 1) {
- byte code[] = {WASM_NO_LOCALS, kExprGetLocal, 0, static_cast<byte>(opcode)};
+ byte code[] = {WASM_NO_LOCALS, kExprGetLocal, 0, static_cast<byte>(opcode),
+ WASM_END};
TestBuildingGraph(&zone, &jsgraph, nullptr, sig, nullptr, code,
code + arraysize(code));
} else {
- CHECK_EQ(2u, sig->parameter_count());
- byte code[] = {WASM_NO_LOCALS, kExprGetLocal, 0, kExprGetLocal, 1,
- static_cast<byte>(opcode)};
+ CHECK_EQ(2, sig->parameter_count());
+ byte code[] = {WASM_NO_LOCALS,
+ kExprGetLocal,
+ 0,
+ kExprGetLocal,
+ 1,
+ static_cast<byte>(opcode),
+ WASM_END};
TestBuildingGraph(&zone, &jsgraph, nullptr, sig, nullptr, code,
code + arraysize(code));
}
@@ -1963,12 +1901,11 @@ TEST(Build_Wasm_SimpleExprs) {
}
WASM_EXEC_TEST(Int32LoadInt8_signext) {
- TestingModule module(execution_mode);
+ WasmRunner<int32_t, int32_t> r(execution_mode);
const int kNumElems = 16;
- int8_t* memory = module.AddMemoryElems<int8_t>(kNumElems);
- module.RandomizeMemory();
+ int8_t* memory = r.module().AddMemoryElems<int8_t>(kNumElems);
+ r.module().RandomizeMemory();
memory[0] = -1;
- WasmRunner<int32_t> r(&module, MachineType::Int32());
BUILD(r, WASM_LOAD_MEM(MachineType::Int8(), WASM_GET_LOCAL(0)));
for (int i = 0; i < kNumElems; ++i) {
@@ -1977,12 +1914,11 @@ WASM_EXEC_TEST(Int32LoadInt8_signext) {
}
WASM_EXEC_TEST(Int32LoadInt8_zeroext) {
- TestingModule module(execution_mode);
+ WasmRunner<int32_t, int32_t> r(execution_mode);
const int kNumElems = 16;
- byte* memory = module.AddMemory(kNumElems);
- module.RandomizeMemory(77);
+ byte* memory = r.module().AddMemory(kNumElems);
+ r.module().RandomizeMemory(77);
memory[0] = 255;
- WasmRunner<int32_t> r(&module, MachineType::Int32());
BUILD(r, WASM_LOAD_MEM(MachineType::Uint8(), WASM_GET_LOCAL(0)));
for (int i = 0; i < kNumElems; ++i) {
@@ -1991,12 +1927,11 @@ WASM_EXEC_TEST(Int32LoadInt8_zeroext) {
}
WASM_EXEC_TEST(Int32LoadInt16_signext) {
- TestingModule module(execution_mode);
+ WasmRunner<int32_t, int32_t> r(execution_mode);
const int kNumBytes = 16;
- byte* memory = module.AddMemory(kNumBytes);
- module.RandomizeMemory(888);
+ byte* memory = r.module().AddMemory(kNumBytes);
+ r.module().RandomizeMemory(888);
memory[1] = 200;
- WasmRunner<int32_t> r(&module, MachineType::Int32());
BUILD(r, WASM_LOAD_MEM(MachineType::Int16(), WASM_GET_LOCAL(0)));
for (int i = 0; i < kNumBytes; i += 2) {
@@ -2006,12 +1941,11 @@ WASM_EXEC_TEST(Int32LoadInt16_signext) {
}
WASM_EXEC_TEST(Int32LoadInt16_zeroext) {
- TestingModule module(execution_mode);
+ WasmRunner<int32_t, int32_t> r(execution_mode);
const int kNumBytes = 16;
- byte* memory = module.AddMemory(kNumBytes);
- module.RandomizeMemory(9999);
+ byte* memory = r.module().AddMemory(kNumBytes);
+ r.module().RandomizeMemory(9999);
memory[1] = 204;
- WasmRunner<int32_t> r(&module, MachineType::Int32());
BUILD(r, WASM_LOAD_MEM(MachineType::Uint16(), WASM_GET_LOCAL(0)));
for (int i = 0; i < kNumBytes; i += 2) {
@@ -2021,9 +1955,8 @@ WASM_EXEC_TEST(Int32LoadInt16_zeroext) {
}
WASM_EXEC_TEST(Int32Global) {
- TestingModule module(execution_mode);
- int32_t* global = module.AddGlobal<int32_t>(kAstI32);
- WasmRunner<int32_t> r(&module, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ int32_t* global = r.module().AddGlobal<int32_t>();
// global = global + p0
BUILD(r,
WASM_SET_GLOBAL(0, WASM_I32_ADD(WASM_GET_GLOBAL(0), WASM_GET_LOCAL(0))),
@@ -2039,14 +1972,13 @@ WASM_EXEC_TEST(Int32Global) {
WASM_EXEC_TEST(Int32Globals_DontAlias) {
const int kNumGlobals = 3;
- TestingModule module(execution_mode);
- int32_t* globals[] = {module.AddGlobal<int32_t>(kAstI32),
- module.AddGlobal<int32_t>(kAstI32),
- module.AddGlobal<int32_t>(kAstI32)};
-
for (int g = 0; g < kNumGlobals; ++g) {
// global = global + p0
- WasmRunner<int32_t> r(&module, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ int32_t* globals[] = {r.module().AddGlobal<int32_t>(),
+ r.module().AddGlobal<int32_t>(),
+ r.module().AddGlobal<int32_t>()};
+
BUILD(r, WASM_SET_GLOBAL(
g, WASM_I32_ADD(WASM_GET_GLOBAL(g), WASM_GET_LOCAL(0))),
WASM_GET_GLOBAL(g));
@@ -2068,9 +2000,8 @@ WASM_EXEC_TEST(Int32Globals_DontAlias) {
}
WASM_EXEC_TEST(Float32Global) {
- TestingModule module(execution_mode);
- float* global = module.AddGlobal<float>(kAstF32);
- WasmRunner<int32_t> r(&module, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ float* global = r.module().AddGlobal<float>();
// global = global + p0
BUILD(r, WASM_SET_GLOBAL(
0, WASM_F32_ADD(WASM_GET_GLOBAL(0),
@@ -2086,9 +2017,8 @@ WASM_EXEC_TEST(Float32Global) {
}
WASM_EXEC_TEST(Float64Global) {
- TestingModule module(execution_mode);
- double* global = module.AddGlobal<double>(kAstF64);
- WasmRunner<int32_t> r(&module, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ double* global = r.module().AddGlobal<double>();
// global = global + p0
BUILD(r, WASM_SET_GLOBAL(
0, WASM_F64_ADD(WASM_GET_GLOBAL(0),
@@ -2104,16 +2034,15 @@ WASM_EXEC_TEST(Float64Global) {
}
WASM_EXEC_TEST(MixedGlobals) {
- TestingModule module(execution_mode);
- int32_t* unused = module.AddGlobal<int32_t>(kAstI32);
- byte* memory = module.AddMemory(32);
+ WasmRunner<int32_t, int32_t> r(execution_mode);
- int32_t* var_int32 = module.AddGlobal<int32_t>(kAstI32);
- uint32_t* var_uint32 = module.AddGlobal<uint32_t>(kAstI32);
- float* var_float = module.AddGlobal<float>(kAstF32);
- double* var_double = module.AddGlobal<double>(kAstF64);
+ int32_t* unused = r.module().AddGlobal<int32_t>();
+ byte* memory = r.module().AddMemory(32);
- WasmRunner<int32_t> r(&module, MachineType::Int32());
+ int32_t* var_int32 = r.module().AddGlobal<int32_t>();
+ uint32_t* var_uint32 = r.module().AddGlobal<uint32_t>();
+ float* var_float = r.module().AddGlobal<float>();
+ double* var_double = r.module().AddGlobal<double>();
BUILD(r, WASM_SET_GLOBAL(1, WASM_LOAD_MEM(MachineType::Int32(), WASM_ZERO)),
WASM_SET_GLOBAL(2, WASM_LOAD_MEM(MachineType::Uint32(), WASM_ZERO)),
@@ -2141,36 +2070,33 @@ WASM_EXEC_TEST(MixedGlobals) {
WASM_EXEC_TEST(CallEmpty) {
const int32_t kExpected = -414444;
+ WasmRunner<int32_t> r(execution_mode);
+
// Build the target function.
- TestSignatures sigs;
- TestingModule module(execution_mode);
- WasmFunctionCompiler t(sigs.i_v(), &module);
- BUILD(t, WASM_I32V_3(kExpected));
- uint32_t index = t.CompileAndAdd();
+ WasmFunctionCompiler& target_func = r.NewFunction<int>();
+ BUILD(target_func, WASM_I32V_3(kExpected));
// Build the calling function.
- WasmRunner<int32_t> r(&module);
- BUILD(r, WASM_CALL_FUNCTION0(index));
+ BUILD(r, WASM_CALL_FUNCTION0(target_func.function_index()));
int32_t result = r.Call();
CHECK_EQ(kExpected, result);
}
WASM_EXEC_TEST(CallF32StackParameter) {
+ WasmRunner<float> r(execution_mode);
+
// Build the target function.
- LocalType param_types[20];
- for (int i = 0; i < 20; ++i) param_types[i] = kAstF32;
+ ValueType param_types[20];
+ for (int i = 0; i < 20; ++i) param_types[i] = kWasmF32;
FunctionSig sig(1, 19, param_types);
- TestingModule module(execution_mode);
- WasmFunctionCompiler t(&sig, &module);
+ WasmFunctionCompiler& t = r.NewFunction(&sig);
BUILD(t, WASM_GET_LOCAL(17));
- uint32_t index = t.CompileAndAdd();
// Build the calling function.
- WasmRunner<float> r(&module);
BUILD(r, WASM_CALL_FUNCTION(
- index, WASM_F32(1.0f), WASM_F32(2.0f), WASM_F32(4.0f),
- WASM_F32(8.0f), WASM_F32(16.0f), WASM_F32(32.0f),
+ t.function_index(), WASM_F32(1.0f), WASM_F32(2.0f),
+ WASM_F32(4.0f), WASM_F32(8.0f), WASM_F32(16.0f), WASM_F32(32.0f),
WASM_F32(64.0f), WASM_F32(128.0f), WASM_F32(256.0f),
WASM_F32(1.5f), WASM_F32(2.5f), WASM_F32(4.5f), WASM_F32(8.5f),
WASM_F32(16.5f), WASM_F32(32.5f), WASM_F32(64.5f),
@@ -2181,18 +2107,17 @@ WASM_EXEC_TEST(CallF32StackParameter) {
}
WASM_EXEC_TEST(CallF64StackParameter) {
+ WasmRunner<double> r(execution_mode);
+
// Build the target function.
- LocalType param_types[20];
- for (int i = 0; i < 20; ++i) param_types[i] = kAstF64;
+ ValueType param_types[20];
+ for (int i = 0; i < 20; ++i) param_types[i] = kWasmF64;
FunctionSig sig(1, 19, param_types);
- TestingModule module(execution_mode);
- WasmFunctionCompiler t(&sig, &module);
+ WasmFunctionCompiler& t = r.NewFunction(&sig);
BUILD(t, WASM_GET_LOCAL(17));
- uint32_t index = t.CompileAndAdd();
// Build the calling function.
- WasmRunner<double> r(&module);
- BUILD(r, WASM_CALL_FUNCTION(index, WASM_F64(1.0), WASM_F64(2.0),
+ BUILD(r, WASM_CALL_FUNCTION(t.function_index(), WASM_F64(1.0), WASM_F64(2.0),
WASM_F64(4.0), WASM_F64(8.0), WASM_F64(16.0),
WASM_F64(32.0), WASM_F64(64.0), WASM_F64(128.0),
WASM_F64(256.0), WASM_F64(1.5), WASM_F64(2.5),
@@ -2205,41 +2130,39 @@ WASM_EXEC_TEST(CallF64StackParameter) {
}
WASM_EXEC_TEST(CallVoid) {
+ WasmRunner<int32_t> r(execution_mode);
+
const byte kMemOffset = 8;
const int32_t kElemNum = kMemOffset / sizeof(int32_t);
const int32_t kExpected = 414444;
// Build the target function.
TestSignatures sigs;
- TestingModule module(execution_mode);
- int32_t* memory = module.AddMemoryElems<int32_t>(16 / sizeof(int32_t));
- module.RandomizeMemory();
- WasmFunctionCompiler t(sigs.v_v(), &module);
- BUILD(t, WASM_STORE_MEM(MachineType::Int32(), WASM_I8(kMemOffset),
+ int32_t* memory = r.module().AddMemoryElems<int32_t>(16 / sizeof(int32_t));
+ r.module().RandomizeMemory();
+ WasmFunctionCompiler& t = r.NewFunction(sigs.v_v());
+ BUILD(t, WASM_STORE_MEM(MachineType::Int32(), WASM_I32V_1(kMemOffset),
WASM_I32V_3(kExpected)));
- uint32_t index = t.CompileAndAdd();
// Build the calling function.
- WasmRunner<int32_t> r(&module);
- BUILD(r, WASM_CALL_FUNCTION0(index),
- WASM_LOAD_MEM(MachineType::Int32(), WASM_I8(kMemOffset)));
+ BUILD(r, WASM_CALL_FUNCTION0(t.function_index()),
+ WASM_LOAD_MEM(MachineType::Int32(), WASM_I32V_1(kMemOffset)));
int32_t result = r.Call();
CHECK_EQ(kExpected, result);
CHECK_EQ(static_cast<int64_t>(kExpected),
- static_cast<int64_t>(module.ReadMemory(&memory[kElemNum])));
+ static_cast<int64_t>(r.module().ReadMemory(&memory[kElemNum])));
}
WASM_EXEC_TEST(Call_Int32Add) {
+ WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
+
// Build the target function.
- TestSignatures sigs;
- TestingModule module(execution_mode);
- WasmFunctionCompiler t(sigs.i_ii(), &module);
+ WasmFunctionCompiler& t = r.NewFunction<int32_t, int32_t, int32_t>();
BUILD(t, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
- uint32_t index = t.CompileAndAdd();
// Build the caller function.
- WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32());
- BUILD(r, WASM_CALL_FUNCTION(index, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
+ BUILD(r, WASM_CALL_FUNCTION(t.function_index(), WASM_GET_LOCAL(0),
+ WASM_GET_LOCAL(1)));
FOR_INT32_INPUTS(i) {
FOR_INT32_INPUTS(j) {
@@ -2251,17 +2174,15 @@ WASM_EXEC_TEST(Call_Int32Add) {
}
WASM_EXEC_TEST(Call_Float32Sub) {
- TestSignatures sigs;
- TestingModule module(execution_mode);
- WasmFunctionCompiler t(sigs.f_ff(), &module);
+ WasmRunner<float, float, float> r(execution_mode);
// Build the target function.
- BUILD(t, WASM_F32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
- uint32_t index = t.CompileAndAdd();
+ WasmFunctionCompiler& target_func = r.NewFunction<float, float, float>();
+ BUILD(target_func, WASM_F32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
- // Builder the caller function.
- WasmRunner<float> r(&module, MachineType::Float32(), MachineType::Float32());
- BUILD(r, WASM_CALL_FUNCTION(index, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
+ // Build the caller function.
+ BUILD(r, WASM_CALL_FUNCTION(target_func.function_index(), WASM_GET_LOCAL(0),
+ WASM_GET_LOCAL(1)));
FOR_FLOAT32_INPUTS(i) {
FOR_FLOAT32_INPUTS(j) { CHECK_FLOAT_EQ(*i - *j, r.Call(*i, *j)); }
@@ -2269,27 +2190,28 @@ WASM_EXEC_TEST(Call_Float32Sub) {
}
WASM_EXEC_TEST(Call_Float64Sub) {
- TestingModule module(execution_mode);
- double* memory = module.AddMemoryElems<double>(16);
- WasmRunner<int32_t> r(&module);
+ WasmRunner<int32_t> r(execution_mode);
+ double* memory = r.module().AddMemoryElems<double>(16);
BUILD(r, WASM_STORE_MEM(
MachineType::Float64(), WASM_ZERO,
- WASM_F64_SUB(WASM_LOAD_MEM(MachineType::Float64(), WASM_ZERO),
- WASM_LOAD_MEM(MachineType::Float64(), WASM_I8(8)))),
- WASM_I8(107));
+ WASM_F64_SUB(
+ WASM_LOAD_MEM(MachineType::Float64(), WASM_ZERO),
+ WASM_LOAD_MEM(MachineType::Float64(), WASM_I32V_1(8)))),
+ WASM_I32V_2(107));
FOR_FLOAT64_INPUTS(i) {
FOR_FLOAT64_INPUTS(j) {
- module.WriteMemory(&memory[0], *i);
- module.WriteMemory(&memory[1], *j);
+ r.module().WriteMemory(&memory[0], *i);
+ r.module().WriteMemory(&memory[1], *j);
double expected = *i - *j;
CHECK_EQ(107, r.Call());
if (expected != expected) {
- CHECK(module.ReadMemory(&memory[0]) != module.ReadMemory(&memory[0]));
+ CHECK(r.module().ReadMemory(&memory[0]) !=
+ r.module().ReadMemory(&memory[0]));
} else {
- CHECK_EQ(expected, module.ReadMemory(&memory[0]));
+ CHECK_EQ(expected, r.module().ReadMemory(&memory[0]));
}
}
}
@@ -2317,28 +2239,25 @@ static void Run_WasmMixedCall_N(WasmExecutionMode execution_mode, int start) {
for (int which = 0; which < num_params; ++which) {
v8::internal::AccountingAllocator allocator;
Zone zone(&allocator, ZONE_NAME);
- TestingModule module(execution_mode);
- module.AddMemory(1024);
+ WasmRunner<int32_t> r(execution_mode);
+ r.module().AddMemory(1024);
MachineType* memtypes = &mixed[start];
MachineType result = memtypes[which];
// =========================================================================
// Build the selector function.
// =========================================================================
- uint32_t index;
FunctionSig::Builder b(&zone, 1, num_params);
- b.AddReturn(WasmOpcodes::LocalTypeFor(result));
+ b.AddReturn(WasmOpcodes::ValueTypeFor(result));
for (int i = 0; i < num_params; ++i) {
- b.AddParam(WasmOpcodes::LocalTypeFor(memtypes[i]));
+ b.AddParam(WasmOpcodes::ValueTypeFor(memtypes[i]));
}
- WasmFunctionCompiler t(b.Build(), &module);
+ WasmFunctionCompiler& t = r.NewFunction(b.Build());
BUILD(t, WASM_GET_LOCAL(which));
- index = t.CompileAndAdd();
// =========================================================================
// Build the calling function.
// =========================================================================
- WasmRunner<int32_t> r(&module);
std::vector<byte> code;
// Load the offset for the store.
@@ -2347,11 +2266,11 @@ static void Run_WasmMixedCall_N(WasmExecutionMode execution_mode, int start) {
// Load the arguments.
for (int i = 0; i < num_params; ++i) {
int offset = (i + 1) * kElemSize;
- ADD_CODE(code, WASM_LOAD_MEM(memtypes[i], WASM_I8(offset)));
+ ADD_CODE(code, WASM_LOAD_MEM(memtypes[i], WASM_I32V_2(offset)));
}
// Call the selector function.
- ADD_CODE(code, kExprCallFunction, static_cast<byte>(index));
+ ADD_CODE(code, WASM_CALL_FUNCTION0(t.function_index()));
// Store the result in memory.
ADD_CODE(code,
@@ -2365,14 +2284,14 @@ static void Run_WasmMixedCall_N(WasmExecutionMode execution_mode, int start) {
// Run the code.
for (int t = 0; t < 10; ++t) {
- module.RandomizeMemory();
+ r.module().RandomizeMemory();
CHECK_EQ(kExpected, r.Call());
int size = WasmOpcodes::MemSize(result);
for (int i = 0; i < size; ++i) {
int base = (which + 1) * kElemSize;
- byte expected = module.raw_mem_at<byte>(base + i);
- byte result = module.raw_mem_at<byte>(i);
+ byte expected = r.module().raw_mem_at<byte>(base + i);
+ byte result = r.module().raw_mem_at<byte>(i);
CHECK_EQ(expected, result);
}
}
@@ -2385,15 +2304,12 @@ WASM_EXEC_TEST(MixedCall_2) { Run_WasmMixedCall_N(execution_mode, 2); }
WASM_EXEC_TEST(MixedCall_3) { Run_WasmMixedCall_N(execution_mode, 3); }
WASM_EXEC_TEST(AddCall) {
- TestSignatures sigs;
- TestingModule module(execution_mode);
- WasmFunctionCompiler t1(sigs.i_ii(), &module);
+ WasmRunner<int32_t, int32_t> r(kExecuteCompiled);
+ WasmFunctionCompiler& t1 = r.NewFunction<int32_t, int32_t, int32_t>();
BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
- t1.CompileAndAdd();
- WasmRunner<int32_t> r(&module, MachineType::Int32());
- byte local = r.AllocateLocal(kAstI32);
- BUILD(r, WASM_SET_LOCAL(local, WASM_I8(99)),
+ byte local = r.AllocateLocal(kWasmI32);
+ BUILD(r, WASM_SET_LOCAL(local, WASM_I32V_2(99)),
WASM_I32_ADD(WASM_CALL_FUNCTION(t1.function_index(), WASM_GET_LOCAL(0),
WASM_GET_LOCAL(0)),
WASM_CALL_FUNCTION(t1.function_index(), WASM_GET_LOCAL(1),
@@ -2406,16 +2322,15 @@ WASM_EXEC_TEST(AddCall) {
WASM_EXEC_TEST(MultiReturnSub) {
FLAG_wasm_mv_prototype = true;
- LocalType storage[] = {kAstI32, kAstI32, kAstI32, kAstI32};
+ WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
+
+ ValueType storage[] = {kWasmI32, kWasmI32, kWasmI32, kWasmI32};
FunctionSig sig_ii_ii(2, 2, storage);
- TestingModule module(execution_mode);
- WasmFunctionCompiler t1(&sig_ii_ii, &module);
+ WasmFunctionCompiler& t1 = r.NewFunction(&sig_ii_ii);
BUILD(t1, WASM_GET_LOCAL(1), WASM_GET_LOCAL(0));
- t1.CompileAndAdd();
- WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32());
- BUILD(r, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1), kExprCallFunction, 0,
- kExprI32Sub);
+ BUILD(r, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
+ WASM_CALL_FUNCTION0(t1.function_index()), kExprI32Sub);
FOR_INT32_INPUTS(i) {
FOR_INT32_INPUTS(j) {
@@ -2427,10 +2342,10 @@ WASM_EXEC_TEST(MultiReturnSub) {
}
template <typename T>
-void RunMultiReturnSelect(WasmExecutionMode execution_mode, LocalType type,
- const T* inputs) {
+void RunMultiReturnSelect(WasmExecutionMode execution_mode, const T* inputs) {
FLAG_wasm_mv_prototype = true;
- LocalType storage[] = {type, type, type, type, type, type};
+ ValueType type = WasmOpcodes::ValueTypeFor(MachineTypeForC<T>());
+ ValueType storage[] = {type, type, type, type, type, type};
const size_t kNumReturns = 2;
const size_t kNumParams = arraysize(storage) - kNumReturns;
FunctionSig sig(kNumReturns, kNumParams, storage);
@@ -2438,30 +2353,25 @@ void RunMultiReturnSelect(WasmExecutionMode execution_mode, LocalType type,
for (size_t i = 0; i < kNumParams; i++) {
for (size_t j = 0; j < kNumParams; j++) {
for (int k = 0; k < 2; k++) {
- TestingModule module(execution_mode);
- WasmFunctionCompiler r1(&sig, &module);
+ WasmRunner<T, T, T, T, T> r(execution_mode);
+ WasmFunctionCompiler& r1 = r.NewFunction(&sig);
BUILD(r1, WASM_GET_LOCAL(i), WASM_GET_LOCAL(j));
- r1.CompileAndAdd();
-
- MachineType machine_type = WasmOpcodes::MachineTypeFor(type);
- WasmRunner<T> r2(&module, machine_type, machine_type, machine_type,
- machine_type);
if (k == 0) {
- BUILD(r2, WASM_CALL_FUNCTION(r1.function_index(), WASM_GET_LOCAL(0),
- WASM_GET_LOCAL(1), WASM_GET_LOCAL(2),
- WASM_GET_LOCAL(3)),
+ BUILD(r, WASM_CALL_FUNCTION(r1.function_index(), WASM_GET_LOCAL(0),
+ WASM_GET_LOCAL(1), WASM_GET_LOCAL(2),
+ WASM_GET_LOCAL(3)),
WASM_DROP);
} else {
- BUILD(r2, WASM_CALL_FUNCTION(r1.function_index(), WASM_GET_LOCAL(0),
- WASM_GET_LOCAL(1), WASM_GET_LOCAL(2),
- WASM_GET_LOCAL(3)),
+ BUILD(r, WASM_CALL_FUNCTION(r1.function_index(), WASM_GET_LOCAL(0),
+ WASM_GET_LOCAL(1), WASM_GET_LOCAL(2),
+ WASM_GET_LOCAL(3)),
kExprSetLocal, 0, WASM_DROP, WASM_GET_LOCAL(0));
}
T expected = inputs[k == 0 ? i : j];
- CHECK_EQ(expected, r2.Call(inputs[0], inputs[1], inputs[2], inputs[3]));
+ CHECK_EQ(expected, r.Call(inputs[0], inputs[1], inputs[2], inputs[3]));
}
}
}
@@ -2469,12 +2379,12 @@ void RunMultiReturnSelect(WasmExecutionMode execution_mode, LocalType type,
WASM_EXEC_TEST(MultiReturnSelect_i32) {
static const int32_t inputs[] = {3333333, 4444444, -55555555, -7777777};
- RunMultiReturnSelect<int32_t>(execution_mode, kAstI32, inputs);
+ RunMultiReturnSelect<int32_t>(execution_mode, inputs);
}
WASM_EXEC_TEST(MultiReturnSelect_f32) {
static const float inputs[] = {33.33333f, 444.4444f, -55555.555f, -77777.77f};
- RunMultiReturnSelect<float>(execution_mode, kAstF32, inputs);
+ RunMultiReturnSelect<float>(execution_mode, inputs);
}
WASM_EXEC_TEST(MultiReturnSelect_i64) {
@@ -2482,60 +2392,60 @@ WASM_EXEC_TEST(MultiReturnSelect_i64) {
// TODO(titzer): implement int64-lowering for multiple return values
static const int64_t inputs[] = {33333338888, 44444446666, -555555553333,
-77777771111};
- RunMultiReturnSelect<int64_t>(execution_mode, kAstI64, inputs);
+ RunMultiReturnSelect<int64_t>(execution_mode, inputs);
#endif
}
WASM_EXEC_TEST(MultiReturnSelect_f64) {
static const double inputs[] = {3.333333, 44444.44, -55.555555, -7777.777};
- RunMultiReturnSelect<double>(execution_mode, kAstF64, inputs);
+ RunMultiReturnSelect<double>(execution_mode, inputs);
}
WASM_EXEC_TEST(ExprBlock2a) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
- BUILD(r, WASM_BLOCK_I(WASM_IF(WASM_GET_LOCAL(0), WASM_BRV(1, WASM_I8(1))),
- WASM_I8(1)));
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ BUILD(r, WASM_BLOCK_I(WASM_IF(WASM_GET_LOCAL(0), WASM_BRV(1, WASM_I32V_1(1))),
+ WASM_I32V_1(1)));
CHECK_EQ(1, r.Call(0));
CHECK_EQ(1, r.Call(1));
}
WASM_EXEC_TEST(ExprBlock2b) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
- BUILD(r, WASM_BLOCK_I(WASM_IF(WASM_GET_LOCAL(0), WASM_BRV(1, WASM_I8(1))),
- WASM_I8(2)));
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ BUILD(r, WASM_BLOCK_I(WASM_IF(WASM_GET_LOCAL(0), WASM_BRV(1, WASM_I32V_1(1))),
+ WASM_I32V_1(2)));
CHECK_EQ(2, r.Call(0));
CHECK_EQ(1, r.Call(1));
}
WASM_EXEC_TEST(ExprBlock2c) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
- BUILD(r, WASM_BLOCK_I(WASM_BRV_IFD(0, WASM_I8(1), WASM_GET_LOCAL(0)),
- WASM_I8(1)));
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ BUILD(r, WASM_BLOCK_I(WASM_BRV_IFD(0, WASM_I32V_1(1), WASM_GET_LOCAL(0)),
+ WASM_I32V_1(1)));
CHECK_EQ(1, r.Call(0));
CHECK_EQ(1, r.Call(1));
}
WASM_EXEC_TEST(ExprBlock2d) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
- BUILD(r, WASM_BLOCK_I(WASM_BRV_IFD(0, WASM_I8(1), WASM_GET_LOCAL(0)),
- WASM_I8(2)));
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ BUILD(r, WASM_BLOCK_I(WASM_BRV_IFD(0, WASM_I32V_1(1), WASM_GET_LOCAL(0)),
+ WASM_I32V_1(2)));
CHECK_EQ(2, r.Call(0));
CHECK_EQ(1, r.Call(1));
}
WASM_EXEC_TEST(ExprBlock_ManualSwitch) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
- BUILD(r, WASM_BLOCK_I(WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(1)),
- WASM_BRV(1, WASM_I8(11))),
- WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(2)),
- WASM_BRV(1, WASM_I8(12))),
- WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(3)),
- WASM_BRV(1, WASM_I8(13))),
- WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(4)),
- WASM_BRV(1, WASM_I8(14))),
- WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(5)),
- WASM_BRV(1, WASM_I8(15))),
- WASM_I8(99)));
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ BUILD(r, WASM_BLOCK_I(WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I32V_1(1)),
+ WASM_BRV(1, WASM_I32V_1(11))),
+ WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I32V_1(2)),
+ WASM_BRV(1, WASM_I32V_1(12))),
+ WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I32V_1(3)),
+ WASM_BRV(1, WASM_I32V_1(13))),
+ WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I32V_1(4)),
+ WASM_BRV(1, WASM_I32V_1(14))),
+ WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I32V_1(5)),
+ WASM_BRV(1, WASM_I32V_1(15))),
+ WASM_I32V_2(99)));
CHECK_EQ(99, r.Call(0));
CHECK_EQ(11, r.Call(1));
CHECK_EQ(12, r.Call(2));
@@ -2546,19 +2456,19 @@ WASM_EXEC_TEST(ExprBlock_ManualSwitch) {
}
WASM_EXEC_TEST(ExprBlock_ManualSwitch_brif) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
- BUILD(r,
- WASM_BLOCK_I(WASM_BRV_IFD(0, WASM_I8(11),
- WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(1))),
- WASM_BRV_IFD(0, WASM_I8(12),
- WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(2))),
- WASM_BRV_IFD(0, WASM_I8(13),
- WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(3))),
- WASM_BRV_IFD(0, WASM_I8(14),
- WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(4))),
- WASM_BRV_IFD(0, WASM_I8(15),
- WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(5))),
- WASM_I8(99)));
+ WasmRunner<int32_t, int32_t> r(execution_mode);
+ BUILD(r, WASM_BLOCK_I(
+ WASM_BRV_IFD(0, WASM_I32V_1(11),
+ WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I32V_1(1))),
+ WASM_BRV_IFD(0, WASM_I32V_1(12),
+ WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I32V_1(2))),
+ WASM_BRV_IFD(0, WASM_I32V_1(13),
+ WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I32V_1(3))),
+ WASM_BRV_IFD(0, WASM_I32V_1(14),
+ WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I32V_1(4))),
+ WASM_BRV_IFD(0, WASM_I32V_1(15),
+ WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I32V_1(5))),
+ WASM_I32V_2(99)));
CHECK_EQ(99, r.Call(0));
CHECK_EQ(11, r.Call(1));
CHECK_EQ(12, r.Call(2));
@@ -2569,13 +2479,14 @@ WASM_EXEC_TEST(ExprBlock_ManualSwitch_brif) {
}
WASM_EXEC_TEST(If_nested) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32(),
- MachineType::Int32());
+ WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
- BUILD(r, WASM_IF_ELSE_I(
- WASM_GET_LOCAL(0),
- WASM_IF_ELSE_I(WASM_GET_LOCAL(1), WASM_I8(11), WASM_I8(12)),
- WASM_IF_ELSE_I(WASM_GET_LOCAL(1), WASM_I8(13), WASM_I8(14))));
+ BUILD(
+ r,
+ WASM_IF_ELSE_I(
+ WASM_GET_LOCAL(0),
+ WASM_IF_ELSE_I(WASM_GET_LOCAL(1), WASM_I32V_1(11), WASM_I32V_1(12)),
+ WASM_IF_ELSE_I(WASM_GET_LOCAL(1), WASM_I32V_1(13), WASM_I32V_1(14))));
CHECK_EQ(11, r.Call(1, 1));
CHECK_EQ(12, r.Call(1, 0));
@@ -2584,26 +2495,25 @@ WASM_EXEC_TEST(If_nested) {
}
WASM_EXEC_TEST(ExprBlock_if) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32());
+ WasmRunner<int32_t, int32_t> r(execution_mode);
- BUILD(r,
- WASM_BLOCK_I(WASM_IF_ELSE_I(WASM_GET_LOCAL(0), WASM_BRV(0, WASM_I8(11)),
- WASM_BRV(1, WASM_I8(14)))));
+ BUILD(r, WASM_BLOCK_I(WASM_IF_ELSE_I(WASM_GET_LOCAL(0),
+ WASM_BRV(0, WASM_I32V_1(11)),
+ WASM_BRV(1, WASM_I32V_1(14)))));
CHECK_EQ(11, r.Call(1));
CHECK_EQ(14, r.Call(0));
}
WASM_EXEC_TEST(ExprBlock_nested_ifs) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32(),
- MachineType::Int32());
+ WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
BUILD(r, WASM_BLOCK_I(WASM_IF_ELSE_I(
WASM_GET_LOCAL(0),
- WASM_IF_ELSE_I(WASM_GET_LOCAL(1), WASM_BRV(0, WASM_I8(11)),
- WASM_BRV(1, WASM_I8(12))),
- WASM_IF_ELSE_I(WASM_GET_LOCAL(1), WASM_BRV(0, WASM_I8(13)),
- WASM_BRV(1, WASM_I8(14))))));
+ WASM_IF_ELSE_I(WASM_GET_LOCAL(1), WASM_BRV(0, WASM_I32V_1(11)),
+ WASM_BRV(1, WASM_I32V_1(12))),
+ WASM_IF_ELSE_I(WASM_GET_LOCAL(1), WASM_BRV(0, WASM_I32V_1(13)),
+ WASM_BRV(1, WASM_I32V_1(14))))));
CHECK_EQ(11, r.Call(1, 1));
CHECK_EQ(12, r.Call(1, 0));
@@ -2611,64 +2521,66 @@ WASM_EXEC_TEST(ExprBlock_nested_ifs) {
CHECK_EQ(14, r.Call(0, 0));
}
-WASM_EXEC_TEST(SimpleCallIndirect) {
+WASM_EXEC_TEST_WITH_TRAP(SimpleCallIndirect) {
TestSignatures sigs;
- TestingModule module(execution_mode);
+ WasmRunner<int32_t, int32_t> r(execution_mode);
- WasmFunctionCompiler t1(sigs.i_ii(), &module);
+ WasmFunctionCompiler& t1 = r.NewFunction(sigs.i_ii());
BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
- t1.CompileAndAdd(/*sig_index*/ 1);
+ t1.SetSigIndex(1);
- WasmFunctionCompiler t2(sigs.i_ii(), &module);
+ WasmFunctionCompiler& t2 = r.NewFunction(sigs.i_ii());
BUILD(t2, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
- t2.CompileAndAdd(/*sig_index*/ 1);
+ t2.SetSigIndex(1);
// Signature table.
- module.AddSignature(sigs.f_ff());
- module.AddSignature(sigs.i_ii());
- module.AddSignature(sigs.d_dd());
+ r.module().AddSignature(sigs.f_ff());
+ r.module().AddSignature(sigs.i_ii());
+ r.module().AddSignature(sigs.d_dd());
// Function table.
- uint16_t indirect_function_table[] = {0, 1};
- module.AddIndirectFunctionTable(indirect_function_table,
- arraysize(indirect_function_table));
- module.PopulateIndirectFunctionTable();
+ uint16_t indirect_function_table[] = {
+ static_cast<uint16_t>(t1.function_index()),
+ static_cast<uint16_t>(t2.function_index())};
+ r.module().AddIndirectFunctionTable(indirect_function_table,
+ arraysize(indirect_function_table));
+ r.module().PopulateIndirectFunctionTable();
- // Builder the caller function.
- WasmRunner<int32_t> r(&module, MachineType::Int32());
- BUILD(r, WASM_CALL_INDIRECT2(1, WASM_GET_LOCAL(0), WASM_I8(66), WASM_I8(22)));
+ // Build the caller function.
+ BUILD(r, WASM_CALL_INDIRECT2(1, WASM_GET_LOCAL(0), WASM_I32V_2(66),
+ WASM_I32V_1(22)));
CHECK_EQ(88, r.Call(0));
CHECK_EQ(44, r.Call(1));
CHECK_TRAP(r.Call(2));
}
-WASM_EXEC_TEST(MultipleCallIndirect) {
+WASM_EXEC_TEST_WITH_TRAP(MultipleCallIndirect) {
TestSignatures sigs;
- TestingModule module(execution_mode);
+ WasmRunner<int32_t, int32_t, int32_t, int32_t> r(execution_mode);
- WasmFunctionCompiler t1(sigs.i_ii(), &module);
+ WasmFunctionCompiler& t1 = r.NewFunction(sigs.i_ii());
BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
- t1.CompileAndAdd(/*sig_index*/ 1);
+ t1.SetSigIndex(1);
- WasmFunctionCompiler t2(sigs.i_ii(), &module);
+ WasmFunctionCompiler& t2 = r.NewFunction(sigs.i_ii());
BUILD(t2, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
- t2.CompileAndAdd(/*sig_index*/ 1);
+ t2.SetSigIndex(1);
// Signature table.
- module.AddSignature(sigs.f_ff());
- module.AddSignature(sigs.i_ii());
- module.AddSignature(sigs.d_dd());
+ r.module().AddSignature(sigs.f_ff());
+ r.module().AddSignature(sigs.i_ii());
+ r.module().AddSignature(sigs.d_dd());
// Function table.
- uint16_t indirect_function_table[] = {0, 1};
- module.AddIndirectFunctionTable(indirect_function_table,
- arraysize(indirect_function_table));
- module.PopulateIndirectFunctionTable();
-
- // Builder the caller function.
- WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32(),
- MachineType::Int32());
+ uint16_t indirect_function_table[] = {
+ static_cast<uint16_t>(t1.function_index()),
+ static_cast<uint16_t>(t2.function_index())};
+ r.module().AddIndirectFunctionTable(indirect_function_table,
+ arraysize(indirect_function_table));
+ r.module().PopulateIndirectFunctionTable();
+
+ // Build the caller function.
BUILD(r, WASM_I32_ADD(
WASM_CALL_INDIRECT2(1, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
WASM_GET_LOCAL(2)),
@@ -2686,49 +2598,49 @@ WASM_EXEC_TEST(MultipleCallIndirect) {
CHECK_TRAP(r.Call(2, 1, 0));
}
-WASM_EXEC_TEST(CallIndirect_EmptyTable) {
+WASM_EXEC_TEST_WITH_TRAP(CallIndirect_EmptyTable) {
TestSignatures sigs;
- TestingModule module(execution_mode);
+ WasmRunner<int32_t, int32_t> r(execution_mode);
// One function.
- WasmFunctionCompiler t1(sigs.i_ii(), &module);
+ WasmFunctionCompiler& t1 = r.NewFunction(sigs.i_ii());
BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
- t1.CompileAndAdd(/*sig_index*/ 1);
+ t1.SetSigIndex(1);
// Signature table.
- module.AddSignature(sigs.f_ff());
- module.AddSignature(sigs.i_ii());
- module.AddIndirectFunctionTable(nullptr, 0);
+ r.module().AddSignature(sigs.f_ff());
+ r.module().AddSignature(sigs.i_ii());
+ r.module().AddIndirectFunctionTable(nullptr, 0);
- // Builder the caller function.
- WasmRunner<int32_t> r(&module, MachineType::Int32());
- BUILD(r, WASM_CALL_INDIRECT2(1, WASM_GET_LOCAL(0), WASM_I8(66), WASM_I8(22)));
+ // Build the caller function.
+ BUILD(r, WASM_CALL_INDIRECT2(1, WASM_GET_LOCAL(0), WASM_I32V_2(66),
+ WASM_I32V_1(22)));
CHECK_TRAP(r.Call(0));
CHECK_TRAP(r.Call(1));
CHECK_TRAP(r.Call(2));
}
-WASM_EXEC_TEST(CallIndirect_canonical) {
+WASM_EXEC_TEST_WITH_TRAP(CallIndirect_canonical) {
TestSignatures sigs;
- TestingModule module(execution_mode);
+ WasmRunner<int32_t, int32_t> r(execution_mode);
- WasmFunctionCompiler t1(sigs.i_ii(), &module);
+ WasmFunctionCompiler& t1 = r.NewFunction(sigs.i_ii());
BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
- t1.CompileAndAdd(/*sig_index*/ 0);
+ t1.SetSigIndex(0);
- WasmFunctionCompiler t2(sigs.i_ii(), &module);
+ WasmFunctionCompiler& t2 = r.NewFunction(sigs.i_ii());
BUILD(t2, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
- t2.CompileAndAdd(/*sig_index*/ 1);
+ t2.SetSigIndex(1);
- WasmFunctionCompiler t3(sigs.f_ff(), &module);
+ WasmFunctionCompiler& t3 = r.NewFunction(sigs.f_ff());
BUILD(t3, WASM_F32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
- t3.CompileAndAdd(/*sig_index*/ 2);
+ t3.SetSigIndex(2);
// Signature table.
- module.AddSignature(sigs.i_ii());
- module.AddSignature(sigs.i_ii());
- module.AddSignature(sigs.f_ff());
+ r.module().AddSignature(sigs.i_ii());
+ r.module().AddSignature(sigs.i_ii());
+ r.module().AddSignature(sigs.f_ff());
// Function table.
uint16_t i1 = static_cast<uint16_t>(t1.function_index());
@@ -2736,13 +2648,13 @@ WASM_EXEC_TEST(CallIndirect_canonical) {
uint16_t i3 = static_cast<uint16_t>(t3.function_index());
uint16_t indirect_function_table[] = {i1, i2, i3, i1, i2};
- module.AddIndirectFunctionTable(indirect_function_table,
- arraysize(indirect_function_table));
- module.PopulateIndirectFunctionTable();
+ r.module().AddIndirectFunctionTable(indirect_function_table,
+ arraysize(indirect_function_table));
+ r.module().PopulateIndirectFunctionTable();
- // Builder the caller function.
- WasmRunner<int32_t> r(&module, MachineType::Int32());
- BUILD(r, WASM_CALL_INDIRECT2(1, WASM_GET_LOCAL(0), WASM_I8(77), WASM_I8(11)));
+ // Build the caller function.
+ BUILD(r, WASM_CALL_INDIRECT2(1, WASM_GET_LOCAL(0), WASM_I32V_2(77),
+ WASM_I32V_1(11)));
CHECK_EQ(88, r.Call(0));
CHECK_EQ(66, r.Call(1));
@@ -2753,64 +2665,63 @@ WASM_EXEC_TEST(CallIndirect_canonical) {
}
WASM_EXEC_TEST(F32Floor) {
- WasmRunner<float> r(execution_mode, MachineType::Float32());
+ WasmRunner<float, float> r(execution_mode);
BUILD(r, WASM_F32_FLOOR(WASM_GET_LOCAL(0)));
FOR_FLOAT32_INPUTS(i) { CHECK_FLOAT_EQ(floorf(*i), r.Call(*i)); }
}
WASM_EXEC_TEST(F32Ceil) {
- WasmRunner<float> r(execution_mode, MachineType::Float32());
+ WasmRunner<float, float> r(execution_mode);
BUILD(r, WASM_F32_CEIL(WASM_GET_LOCAL(0)));
FOR_FLOAT32_INPUTS(i) { CHECK_FLOAT_EQ(ceilf(*i), r.Call(*i)); }
}
WASM_EXEC_TEST(F32Trunc) {
- WasmRunner<float> r(execution_mode, MachineType::Float32());
+ WasmRunner<float, float> r(execution_mode);
BUILD(r, WASM_F32_TRUNC(WASM_GET_LOCAL(0)));
FOR_FLOAT32_INPUTS(i) { CHECK_FLOAT_EQ(truncf(*i), r.Call(*i)); }
}
WASM_EXEC_TEST(F32NearestInt) {
- WasmRunner<float> r(execution_mode, MachineType::Float32());
+ WasmRunner<float, float> r(execution_mode);
BUILD(r, WASM_F32_NEARESTINT(WASM_GET_LOCAL(0)));
FOR_FLOAT32_INPUTS(i) { CHECK_FLOAT_EQ(nearbyintf(*i), r.Call(*i)); }
}
WASM_EXEC_TEST(F64Floor) {
- WasmRunner<double> r(execution_mode, MachineType::Float64());
+ WasmRunner<double, double> r(execution_mode);
BUILD(r, WASM_F64_FLOOR(WASM_GET_LOCAL(0)));
FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(floor(*i), r.Call(*i)); }
}
WASM_EXEC_TEST(F64Ceil) {
- WasmRunner<double> r(execution_mode, MachineType::Float64());
+ WasmRunner<double, double> r(execution_mode);
BUILD(r, WASM_F64_CEIL(WASM_GET_LOCAL(0)));
FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(ceil(*i), r.Call(*i)); }
}
WASM_EXEC_TEST(F64Trunc) {
- WasmRunner<double> r(execution_mode, MachineType::Float64());
+ WasmRunner<double, double> r(execution_mode);
BUILD(r, WASM_F64_TRUNC(WASM_GET_LOCAL(0)));
FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(trunc(*i), r.Call(*i)); }
}
WASM_EXEC_TEST(F64NearestInt) {
- WasmRunner<double> r(execution_mode, MachineType::Float64());
+ WasmRunner<double, double> r(execution_mode);
BUILD(r, WASM_F64_NEARESTINT(WASM_GET_LOCAL(0)));
FOR_FLOAT64_INPUTS(i) { CHECK_DOUBLE_EQ(nearbyint(*i), r.Call(*i)); }
}
WASM_EXEC_TEST(F32Min) {
- WasmRunner<float> r(execution_mode, MachineType::Float32(),
- MachineType::Float32());
+ WasmRunner<float, float, float> r(execution_mode);
BUILD(r, WASM_F32_MIN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_FLOAT32_INPUTS(i) {
@@ -2819,8 +2730,7 @@ WASM_EXEC_TEST(F32Min) {
}
WASM_EXEC_TEST(F64Min) {
- WasmRunner<double> r(execution_mode, MachineType::Float64(),
- MachineType::Float64());
+ WasmRunner<double, double, double> r(execution_mode);
BUILD(r, WASM_F64_MIN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_FLOAT64_INPUTS(i) {
@@ -2829,8 +2739,7 @@ WASM_EXEC_TEST(F64Min) {
}
WASM_EXEC_TEST(F32Max) {
- WasmRunner<float> r(execution_mode, MachineType::Float32(),
- MachineType::Float32());
+ WasmRunner<float, float, float> r(execution_mode);
BUILD(r, WASM_F32_MAX(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_FLOAT32_INPUTS(i) {
@@ -2839,8 +2748,7 @@ WASM_EXEC_TEST(F32Max) {
}
WASM_EXEC_TEST(F64Max) {
- WasmRunner<double> r(execution_mode, MachineType::Float64(),
- MachineType::Float64());
+ WasmRunner<double, double, double> r(execution_mode);
BUILD(r, WASM_F64_MAX(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_FLOAT64_INPUTS(i) {
@@ -2851,8 +2759,8 @@ WASM_EXEC_TEST(F64Max) {
}
}
-WASM_EXEC_TEST(I32SConvertF32) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Float32());
+WASM_EXEC_TEST_WITH_TRAP(I32SConvertF32) {
+ WasmRunner<int32_t, float> r(execution_mode);
BUILD(r, WASM_I32_SCONVERT_F32(WASM_GET_LOCAL(0)));
// The upper bound is (INT32_MAX + 1), which is the lowest float-representable
@@ -2871,8 +2779,8 @@ WASM_EXEC_TEST(I32SConvertF32) {
}
}
-WASM_EXEC_TEST(I32SConvertF64) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Float64());
+WASM_EXEC_TEST_WITH_TRAP(I32SConvertF64) {
+ WasmRunner<int32_t, double> r(execution_mode);
BUILD(r, WASM_I32_SCONVERT_F64(WASM_GET_LOCAL(0)));
// The upper bound is (INT32_MAX + 1), which is the lowest double-
@@ -2890,8 +2798,8 @@ WASM_EXEC_TEST(I32SConvertF64) {
}
}
-WASM_EXEC_TEST(I32UConvertF32) {
- WasmRunner<uint32_t> r(execution_mode, MachineType::Float32());
+WASM_EXEC_TEST_WITH_TRAP(I32UConvertF32) {
+ WasmRunner<uint32_t, float> r(execution_mode);
BUILD(r, WASM_I32_UCONVERT_F32(WASM_GET_LOCAL(0)));
// The upper bound is (UINT32_MAX + 1), which is the lowest
// float-representable number above UINT32_MAX which cannot be represented as
@@ -2907,8 +2815,8 @@ WASM_EXEC_TEST(I32UConvertF32) {
}
}
-WASM_EXEC_TEST(I32UConvertF64) {
- WasmRunner<uint32_t> r(execution_mode, MachineType::Float64());
+WASM_EXEC_TEST_WITH_TRAP(I32UConvertF64) {
+ WasmRunner<uint32_t, double> r(execution_mode);
BUILD(r, WASM_I32_UCONVERT_F64(WASM_GET_LOCAL(0)));
// The upper bound is (UINT32_MAX + 1), which is the lowest
// double-representable number above UINT32_MAX which cannot be represented as
@@ -2925,8 +2833,7 @@ WASM_EXEC_TEST(I32UConvertF64) {
}
WASM_EXEC_TEST(F64CopySign) {
- WasmRunner<double> r(execution_mode, MachineType::Float64(),
- MachineType::Float64());
+ WasmRunner<double, double, double> r(execution_mode);
BUILD(r, WASM_F64_COPYSIGN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_FLOAT64_INPUTS(i) {
@@ -2935,8 +2842,7 @@ WASM_EXEC_TEST(F64CopySign) {
}
WASM_EXEC_TEST(F32CopySign) {
- WasmRunner<float> r(execution_mode, MachineType::Float32(),
- MachineType::Float32());
+ WasmRunner<float, float, float> r(execution_mode);
BUILD(r, WASM_F32_COPYSIGN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
FOR_FLOAT32_INPUTS(i) {
@@ -2944,44 +2850,39 @@ WASM_EXEC_TEST(F32CopySign) {
}
}
-static void CompileCallIndirectMany(LocalType param) {
+static void CompileCallIndirectMany(ValueType param) {
// Make sure we don't run out of registers when compiling indirect calls
// with many many parameters.
TestSignatures sigs;
for (byte num_params = 0; num_params < 40; ++num_params) {
- v8::internal::AccountingAllocator allocator;
- Zone zone(&allocator, ZONE_NAME);
- HandleScope scope(CcTest::InitIsolateOnce());
- TestingModule module(kExecuteCompiled);
- FunctionSig* sig = sigs.many(&zone, kAstStmt, param, num_params);
+ WasmRunner<void> r(kExecuteCompiled);
+ FunctionSig* sig = sigs.many(r.zone(), kWasmStmt, param, num_params);
- module.AddSignature(sig);
- module.AddSignature(sig);
- module.AddIndirectFunctionTable(nullptr, 0);
+ r.module().AddSignature(sig);
+ r.module().AddSignature(sig);
+ r.module().AddIndirectFunctionTable(nullptr, 0);
- WasmFunctionCompiler t(sig, &module);
+ WasmFunctionCompiler& t = r.NewFunction(sig);
std::vector<byte> code;
for (byte p = 0; p < num_params; ++p) {
ADD_CODE(code, kExprGetLocal, p);
}
- ADD_CODE(code, kExprI8Const, 0);
+ ADD_CODE(code, kExprI32Const, 0);
ADD_CODE(code, kExprCallIndirect, 1, TABLE_ZERO);
t.Build(&code[0], &code[0] + code.size());
- t.Compile();
}
}
-TEST(Compile_Wasm_CallIndirect_Many_i32) { CompileCallIndirectMany(kAstI32); }
+TEST(Compile_Wasm_CallIndirect_Many_i32) { CompileCallIndirectMany(kWasmI32); }
-TEST(Compile_Wasm_CallIndirect_Many_f32) { CompileCallIndirectMany(kAstF32); }
+TEST(Compile_Wasm_CallIndirect_Many_f32) { CompileCallIndirectMany(kWasmF32); }
-TEST(Compile_Wasm_CallIndirect_Many_f64) { CompileCallIndirectMany(kAstF64); }
+TEST(Compile_Wasm_CallIndirect_Many_f64) { CompileCallIndirectMany(kWasmF64); }
-WASM_EXEC_TEST(Int32RemS_dead) {
- WasmRunner<int32_t> r(execution_mode, MachineType::Int32(),
- MachineType::Int32());
+WASM_EXEC_TEST_WITH_TRAP(Int32RemS_dead) {
+ WasmRunner<int32_t, int32_t, int32_t> r(execution_mode);
BUILD(r, WASM_I32_REMS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), WASM_DROP,
WASM_ZERO);
const int32_t kMin = std::numeric_limits<int32_t>::min();
diff --git a/deps/v8/test/cctest/wasm/test-wasm-breakpoints.cc b/deps/v8/test/cctest/wasm/test-wasm-breakpoints.cc
new file mode 100644
index 0000000000..d2374a44c0
--- /dev/null
+++ b/deps/v8/test/cctest/wasm/test-wasm-breakpoints.cc
@@ -0,0 +1,70 @@
+// 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/debug/debug-interface.h"
+#include "src/wasm/wasm-macro-gen.h"
+#include "src/wasm/wasm-objects.h"
+
+#include "test/cctest/cctest.h"
+#include "test/cctest/compiler/value-helper.h"
+#include "test/cctest/wasm/wasm-run-utils.h"
+#include "test/common/wasm/test-signatures.h"
+
+using namespace v8::internal;
+using namespace v8::internal::wasm;
+namespace debug = v8::debug;
+
+namespace {
+
+void CheckLocations(
+ WasmCompiledModule *compiled_module, debug::Location start,
+ debug::Location end,
+ std::initializer_list<debug::Location> expected_locations_init) {
+ std::vector<debug::Location> locations;
+ bool success =
+ compiled_module->GetPossibleBreakpoints(start, end, &locations);
+ CHECK(success);
+
+ printf("got %d locations: ", static_cast<int>(locations.size()));
+ for (size_t i = 0, e = locations.size(); i != e; ++i) {
+ printf("%s<%d,%d>", i == 0 ? "" : ", ", locations[i].GetLineNumber(),
+ locations[i].GetColumnNumber());
+ }
+ printf("\n");
+
+ std::vector<debug::Location> expected_locations(expected_locations_init);
+ CHECK_EQ(expected_locations.size(), locations.size());
+ for (size_t i = 0, e = locations.size(); i != e; ++i) {
+ CHECK_EQ(expected_locations[i].GetLineNumber(),
+ locations[i].GetLineNumber());
+ CHECK_EQ(expected_locations[i].GetColumnNumber(),
+ locations[i].GetColumnNumber());
+ }
+}
+void CheckLocationsFail(WasmCompiledModule *compiled_module,
+ debug::Location start, debug::Location end) {
+ std::vector<debug::Location> locations;
+ bool success =
+ compiled_module->GetPossibleBreakpoints(start, end, &locations);
+ CHECK(!success);
+}
+
+} // namespace
+
+TEST(CollectPossibleBreakpoints) {
+ WasmRunner<int> runner(kExecuteCompiled);
+
+ BUILD(runner, WASM_NOP, WASM_I32_ADD(WASM_ZERO, WASM_ONE));
+
+ Handle<WasmInstanceObject> instance = runner.module().instance_object();
+ std::vector<debug::Location> locations;
+ CheckLocations(instance->compiled_module(), {0, 0}, {1, 0},
+ {{0, 1}, {0, 2}, {0, 4}, {0, 6}, {0, 7}});
+ CheckLocations(instance->compiled_module(), {0, 2}, {0, 4}, {{0, 2}});
+ CheckLocations(instance->compiled_module(), {0, 2}, {0, 5}, {{0, 2}, {0, 4}});
+ CheckLocations(instance->compiled_module(), {0, 7}, {0, 8}, {{0, 7}});
+ CheckLocations(instance->compiled_module(), {0, 7}, {1, 0}, {{0, 7}});
+ CheckLocations(instance->compiled_module(), {0, 8}, {1, 0}, {});
+ CheckLocationsFail(instance->compiled_module(), {0, 9}, {1, 0});
+}
diff --git a/deps/v8/test/cctest/wasm/test-wasm-stack.cc b/deps/v8/test/cctest/wasm/test-wasm-stack.cc
index a0c2e73f9d..357a4e487e 100644
--- a/deps/v8/test/cctest/wasm/test-wasm-stack.cc
+++ b/deps/v8/test/cctest/wasm/test-wasm-stack.cc
@@ -76,25 +76,22 @@ void CheckExceptionInfos(Handle<Object> exc,
// Call from JS to WASM to JS and throw an Error from JS.
TEST(CollectDetailedWasmStack_ExplicitThrowFromJs) {
+ WasmRunner<void> r(kExecuteCompiled);
TestSignatures sigs;
- TestingModule module;
- // Initialize WasmFunctionCompiler first, since it sets up the HandleScope.
- WasmFunctionCompiler comp1(sigs.v_v(), &module);
-
- uint32_t js_throwing_index = module.AddJsFunction(
+ uint32_t js_throwing_index = r.module().AddJsFunction(
sigs.v_v(),
"(function js() {\n function a() {\n throw new Error(); };\n a(); })");
// Add a nop such that we don't always get position 1.
- BUILD(comp1, WASM_NOP, WASM_CALL_FUNCTION0(js_throwing_index));
- uint32_t wasm_index = comp1.CompileAndAdd();
+ BUILD(r, WASM_NOP, WASM_CALL_FUNCTION0(js_throwing_index));
+ uint32_t wasm_index_1 = r.function()->func_index;
- WasmFunctionCompiler comp2(sigs.v_v(), &module);
- BUILD(comp2, WASM_CALL_FUNCTION0(wasm_index));
- uint32_t wasm_index_2 = comp2.CompileAndAdd();
+ WasmFunctionCompiler& f2 = r.NewFunction<void>("call_main");
+ BUILD(f2, WASM_CALL_FUNCTION0(wasm_index_1));
+ uint32_t wasm_index_2 = f2.function_index();
- Handle<JSFunction> js_wasm_wrapper = module.WrapCode(wasm_index_2);
+ Handle<JSFunction> js_wasm_wrapper = r.module().WrapCode(wasm_index_2);
Handle<JSFunction> js_trampoline = Handle<JSFunction>::cast(
v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
@@ -107,16 +104,17 @@ TEST(CollectDetailedWasmStack_ExplicitThrowFromJs) {
MaybeHandle<Object> maybe_exc;
Handle<Object> args[] = {js_wasm_wrapper};
MaybeHandle<Object> returnObjMaybe =
- Execution::TryCall(isolate, js_trampoline, global, 1, args, &maybe_exc);
+ Execution::TryCall(isolate, js_trampoline, global, 1, args,
+ Execution::MessageHandling::kReport, &maybe_exc);
CHECK(returnObjMaybe.is_null());
// Line and column are 1-based, so add 1 for the expected wasm output.
ExceptionInfo expected_exceptions[] = {
- {"a", 3, 8}, // -
- {"js", 4, 2}, // -
- {"<WASM UNNAMED>", static_cast<int>(wasm_index) + 1, 3}, // -
- {"<WASM UNNAMED>", static_cast<int>(wasm_index_2) + 1, 2}, // -
- {"callFn", 1, 24} // -
+ {"a", 3, 8}, // -
+ {"js", 4, 2}, // -
+ {"main", static_cast<int>(wasm_index_1) + 1, 3}, // -
+ {"call_main", static_cast<int>(wasm_index_2) + 1, 2}, // -
+ {"callFn", 1, 24} // -
};
CheckExceptionInfos(maybe_exc.ToHandleChecked(), expected_exceptions);
}
@@ -124,21 +122,18 @@ TEST(CollectDetailedWasmStack_ExplicitThrowFromJs) {
// Trigger a trap in WASM, stack should be JS -> WASM -> WASM.
TEST(CollectDetailedWasmStack_WasmError) {
TestSignatures sigs;
- TestingModule module;
-
- WasmFunctionCompiler comp1(sigs.i_v(), &module,
- ArrayVector("exec_unreachable"));
+ WasmRunner<int> r(kExecuteCompiled);
// Set the execution context, such that a runtime error can be thrown.
- comp1.SetModuleContext();
- BUILD(comp1, WASM_UNREACHABLE);
- uint32_t wasm_index = comp1.CompileAndAdd();
+ r.SetModuleContext();
+
+ BUILD(r, WASM_UNREACHABLE);
+ uint32_t wasm_index_1 = r.function()->func_index;
- WasmFunctionCompiler comp2(sigs.i_v(), &module,
- ArrayVector("call_exec_unreachable"));
- BUILD(comp2, WASM_CALL_FUNCTION0(wasm_index));
- uint32_t wasm_index_2 = comp2.CompileAndAdd();
+ WasmFunctionCompiler& f2 = r.NewFunction<int>("call_main");
+ BUILD(f2, WASM_CALL_FUNCTION0(0));
+ uint32_t wasm_index_2 = f2.function_index();
- Handle<JSFunction> js_wasm_wrapper = module.WrapCode(wasm_index_2);
+ Handle<JSFunction> js_wasm_wrapper = r.module().WrapCode(wasm_index_2);
Handle<JSFunction> js_trampoline = Handle<JSFunction>::cast(
v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
@@ -151,14 +146,15 @@ TEST(CollectDetailedWasmStack_WasmError) {
MaybeHandle<Object> maybe_exc;
Handle<Object> args[] = {js_wasm_wrapper};
MaybeHandle<Object> maybe_return_obj =
- Execution::TryCall(isolate, js_trampoline, global, 1, args, &maybe_exc);
+ Execution::TryCall(isolate, js_trampoline, global, 1, args,
+ Execution::MessageHandling::kReport, &maybe_exc);
CHECK(maybe_return_obj.is_null());
// Line and column are 1-based, so add 1 for the expected wasm output.
ExceptionInfo expected_exceptions[] = {
- {"<WASM UNNAMED>", static_cast<int>(wasm_index) + 1, 2}, // -
- {"<WASM UNNAMED>", static_cast<int>(wasm_index_2) + 1, 2}, // -
- {"callFn", 1, 24} //-
+ {"main", static_cast<int>(wasm_index_1) + 1, 2}, // -
+ {"call_main", static_cast<int>(wasm_index_2) + 1, 2}, // -
+ {"callFn", 1, 24} //-
};
CheckExceptionInfos(maybe_exc.ToHandleChecked(), expected_exceptions);
}
diff --git a/deps/v8/test/cctest/wasm/test-wasm-trap-position.cc b/deps/v8/test/cctest/wasm/test-wasm-trap-position.cc
index bd4e82dc4c..0418d46bab 100644
--- a/deps/v8/test/cctest/wasm/test-wasm-trap-position.cc
+++ b/deps/v8/test/cctest/wasm/test-wasm-trap-position.cc
@@ -62,17 +62,15 @@ void CheckExceptionInfos(Handle<Object> exc,
// Trigger a trap for executing unreachable.
TEST(Unreachable) {
+ WasmRunner<void> r(kExecuteCompiled);
TestSignatures sigs;
- TestingModule module;
-
- WasmFunctionCompiler comp1(sigs.v_v(), &module,
- ArrayVector("exec_unreachable"));
// Set the execution context, such that a runtime error can be thrown.
- comp1.SetModuleContext();
- BUILD(comp1, WASM_UNREACHABLE);
- uint32_t wasm_index = comp1.CompileAndAdd();
+ r.SetModuleContext();
+
+ BUILD(r, WASM_UNREACHABLE);
+ uint32_t wasm_index = r.function()->func_index;
- Handle<JSFunction> js_wasm_wrapper = module.WrapCode(wasm_index);
+ Handle<JSFunction> js_wasm_wrapper = r.module().WrapCode(wasm_index);
Handle<JSFunction> js_trampoline = Handle<JSFunction>::cast(
v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
@@ -85,36 +83,37 @@ TEST(Unreachable) {
MaybeHandle<Object> maybe_exc;
Handle<Object> args[] = {js_wasm_wrapper};
MaybeHandle<Object> returnObjMaybe =
- Execution::TryCall(isolate, js_trampoline, global, 1, args, &maybe_exc);
+ Execution::TryCall(isolate, js_trampoline, global, 1, args,
+ Execution::MessageHandling::kReport, &maybe_exc);
CHECK(returnObjMaybe.is_null());
// Line and column are 1-based, so add 1 for the expected wasm output.
ExceptionInfo expected_exceptions[] = {
- {"<WASM UNNAMED>", static_cast<int>(wasm_index) + 1, 2}, // --
- {"callFn", 1, 24} // --
+ {"main", static_cast<int>(wasm_index) + 1, 2}, // --
+ {"callFn", 1, 24} // --
};
CheckExceptionInfos(maybe_exc.ToHandleChecked(), expected_exceptions);
}
// Trigger a trap for loading from out-of-bounds.
TEST(IllegalLoad) {
+ WasmRunner<void> r(kExecuteCompiled);
TestSignatures sigs;
- TestingModule module;
-
- WasmFunctionCompiler comp1(sigs.v_v(), &module, ArrayVector("mem_oob"));
// Set the execution context, such that a runtime error can be thrown.
- comp1.SetModuleContext();
- BUILD(comp1, WASM_IF(WASM_ONE, WASM_SEQ(WASM_LOAD_MEM(MachineType::Int32(),
- WASM_I32V_1(-3)),
- WASM_DROP)));
- uint32_t wasm_index = comp1.CompileAndAdd();
+ r.SetModuleContext();
+ r.module().AddMemory(0L);
+
+ BUILD(r, WASM_IF(WASM_ONE, WASM_SEQ(WASM_LOAD_MEM(MachineType::Int32(),
+ WASM_I32V_1(-3)),
+ WASM_DROP)));
+ uint32_t wasm_index_1 = r.function()->func_index;
- WasmFunctionCompiler comp2(sigs.v_v(), &module, ArrayVector("call_mem_oob"));
+ WasmFunctionCompiler& f2 = r.NewFunction<void>("call_main");
// Insert a NOP such that the position of the call is not one.
- BUILD(comp2, WASM_NOP, WASM_CALL_FUNCTION0(wasm_index));
- uint32_t wasm_index_2 = comp2.CompileAndAdd();
+ BUILD(f2, WASM_NOP, WASM_CALL_FUNCTION0(wasm_index_1));
+ uint32_t wasm_index_2 = f2.function_index();
- Handle<JSFunction> js_wasm_wrapper = module.WrapCode(wasm_index_2);
+ Handle<JSFunction> js_wasm_wrapper = r.module().WrapCode(wasm_index_2);
Handle<JSFunction> js_trampoline = Handle<JSFunction>::cast(
v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
@@ -127,14 +126,15 @@ TEST(IllegalLoad) {
MaybeHandle<Object> maybe_exc;
Handle<Object> args[] = {js_wasm_wrapper};
MaybeHandle<Object> returnObjMaybe =
- Execution::TryCall(isolate, js_trampoline, global, 1, args, &maybe_exc);
+ Execution::TryCall(isolate, js_trampoline, global, 1, args,
+ Execution::MessageHandling::kReport, &maybe_exc);
CHECK(returnObjMaybe.is_null());
// Line and column are 1-based, so add 1 for the expected wasm output.
ExceptionInfo expected_exceptions[] = {
- {"<WASM UNNAMED>", static_cast<int>(wasm_index) + 1, 8}, // --
- {"<WASM UNNAMED>", static_cast<int>(wasm_index_2) + 1, 3}, // --
- {"callFn", 1, 24} // --
+ {"main", static_cast<int>(wasm_index_1) + 1, 8}, // --
+ {"call_main", static_cast<int>(wasm_index_2) + 1, 3}, // --
+ {"callFn", 1, 24} // --
};
CheckExceptionInfos(maybe_exc.ToHandleChecked(), expected_exceptions);
}
diff --git a/deps/v8/test/cctest/wasm/wasm-run-utils.h b/deps/v8/test/cctest/wasm/wasm-run-utils.h
index 284b21c7c4..782e7d9635 100644
--- a/deps/v8/test/cctest/wasm/wasm-run-utils.h
+++ b/deps/v8/test/cctest/wasm/wasm-run-utils.h
@@ -5,9 +5,11 @@
#ifndef WASM_RUN_UTILS_H
#define WASM_RUN_UTILS_H
+#include <setjmp.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
+#include <array>
#include <memory>
#include "src/base/utils/random-number-generator.h"
@@ -21,7 +23,8 @@
#include "src/compiler/pipeline.h"
#include "src/compiler/wasm-compiler.h"
#include "src/compiler/zone-stats.h"
-#include "src/wasm/ast-decoder.h"
+#include "src/wasm/function-body-decoder.h"
+#include "src/wasm/wasm-external-refs.h"
#include "src/wasm/wasm-interpreter.h"
#include "src/wasm/wasm-js.h"
#include "src/wasm/wasm-macro-gen.h"
@@ -49,7 +52,6 @@ enum WasmExecutionMode { kExecuteInterpreted, kExecuteCompiled };
CHECK_EQ(0xdeadbeefdeadbeef, (bit_cast<uint64_t>(x)) & 0xFFFFFFFFFFFFFFFF)
#define CHECK_TRAP(x) CHECK_TRAP32(x)
-#define WASM_RUNNER_MAX_NUM_PARAMETERS 4
#define WASM_WRAPPER_RETURN_VALUE 8754
#define BUILD(r, ...) \
@@ -71,23 +73,26 @@ const uint32_t kMaxGlobalsSize = 128;
// {WasmInstance}.
class TestingModule : public ModuleEnv {
public:
- explicit TestingModule(WasmExecutionMode mode = kExecuteCompiled)
- : execution_mode_(mode),
+ explicit TestingModule(Zone* zone, WasmExecutionMode mode = kExecuteCompiled)
+ : ModuleEnv(&module_, &instance_),
+ execution_mode_(mode),
instance_(&module_),
isolate_(CcTest::InitIsolateOnce()),
global_offset(0),
interpreter_(mode == kExecuteInterpreted
- ? new WasmInterpreter(&instance_, &allocator_)
+ ? new WasmInterpreter(
+ ModuleBytesEnv(&module_, &instance_,
+ Vector<const byte>::empty()),
+ zone->allocator())
: nullptr) {
- module = &module_;
- instance = &instance_;
+ WasmJs::Install(isolate_);
instance->module = &module_;
instance->globals_start = global_data;
module_.globals_size = kMaxGlobalsSize;
instance->mem_start = nullptr;
instance->mem_size = 0;
- origin = kWasmOrigin;
memset(global_data, 0, sizeof(global_data));
+ instance_object_ = InitInstanceObject();
}
~TestingModule() {
@@ -97,13 +102,15 @@ class TestingModule : public ModuleEnv {
if (interpreter_) delete interpreter_;
}
- void ChangeOriginToAsmjs() { origin = kAsmJsOrigin; }
+ void ChangeOriginToAsmjs() { module_.origin = kAsmJsOrigin; }
byte* AddMemory(uint32_t size) {
+ CHECK(!module_.has_memory);
CHECK_NULL(instance->mem_start);
- CHECK_EQ(0u, instance->mem_size);
+ CHECK_EQ(0, instance->mem_size);
+ module_.has_memory = true;
instance->mem_start = reinterpret_cast<byte*>(malloc(size));
- CHECK(instance->mem_start);
+ CHECK(size == 0 || instance->mem_start);
memset(instance->mem_start, 0, size);
instance->mem_size = size;
return raw_mem_start<byte>();
@@ -116,7 +123,8 @@ class TestingModule : public ModuleEnv {
}
template <typename T>
- T* AddGlobal(LocalType type) {
+ T* AddGlobal(
+ ValueType type = WasmOpcodes::ValueTypeFor(MachineTypeForC<T>())) {
const WasmGlobal* global = AddGlobal(type);
return reinterpret_cast<T*>(instance->globals_start + global->offset);
}
@@ -176,7 +184,11 @@ class TestingModule : public ModuleEnv {
rng.NextBytes(raw, end - raw);
}
- uint32_t AddFunction(FunctionSig* sig, Handle<Code> code) {
+ void SetMaxMemPages(uint32_t max_mem_pages) {
+ module_.max_mem_pages = max_mem_pages;
+ }
+
+ uint32_t AddFunction(FunctionSig* sig, Handle<Code> code, const char* name) {
if (module->functions.size() == 0) {
// TODO(titzer): Reserving space here to avoid the underlying WasmFunction
// structs from moving.
@@ -184,6 +196,11 @@ class TestingModule : public ModuleEnv {
}
uint32_t index = static_cast<uint32_t>(module->functions.size());
module_.functions.push_back({sig, index, 0, 0, 0, 0, 0, false, false});
+ if (name) {
+ Vector<const byte> name_vec = Vector<const byte>::cast(CStrVector(name));
+ module_.functions.back().name_offset = AddBytes(name_vec);
+ module_.functions.back().name_length = name_vec.length();
+ }
instance->function_code.push_back(code);
if (interpreter_) {
const WasmFunction* function = &module->functions.back();
@@ -197,26 +214,24 @@ class TestingModule : public ModuleEnv {
uint32_t AddJsFunction(FunctionSig* sig, const char* source) {
Handle<JSFunction> jsfunc = Handle<JSFunction>::cast(v8::Utils::OpenHandle(
*v8::Local<v8::Function>::Cast(CompileRun(source))));
- uint32_t index = AddFunction(sig, Handle<Code>::null());
- Handle<Code> code =
- CompileWasmToJSWrapper(isolate_, jsfunc, sig, index,
- Handle<String>::null(), Handle<String>::null());
+ uint32_t index = AddFunction(sig, Handle<Code>::null(), nullptr);
+ Handle<Code> code = CompileWasmToJSWrapper(
+ isolate_, jsfunc, sig, index, Handle<String>::null(),
+ Handle<String>::null(), module->origin);
instance->function_code[index] = code;
return index;
}
Handle<JSFunction> WrapCode(uint32_t index) {
// Wrap the code so it can be called as a JS function.
- Handle<String> name = isolate_->factory()->NewStringFromStaticChars("main");
Handle<WasmInstanceObject> instance_obj(0, isolate_);
Handle<Code> code = instance->function_code[index];
- WasmJs::InstallWasmMapsIfNeeded(isolate_, isolate_->native_context());
Handle<Code> ret_code =
- compiler::CompileJSToWasmWrapper(isolate_, this, code, index);
+ compiler::CompileJSToWasmWrapper(isolate_, &module_, code, index);
Handle<JSFunction> ret = WasmExportedFunction::New(
- isolate_, instance_obj, name, ret_code,
+ isolate_, instance_obj, MaybeHandle<String>(), static_cast<int>(index),
static_cast<int>(this->module->functions[index].sig->parameter_count()),
- static_cast<int>(index));
+ ret_code);
return ret;
}
@@ -238,40 +253,59 @@ class TestingModule : public ModuleEnv {
}
instance->function_tables.push_back(
- isolate_->factory()->NewFixedArray(table_size * 2));
+ isolate_->factory()->NewFixedArray(table_size));
+ instance->signature_tables.push_back(
+ isolate_->factory()->NewFixedArray(table_size));
}
void PopulateIndirectFunctionTable() {
+ if (execution_mode_ == kExecuteInterpreted) return;
// Initialize the fixed arrays in instance->function_tables.
for (uint32_t i = 0; i < instance->function_tables.size(); i++) {
WasmIndirectFunctionTable& table = module_.function_tables[i];
- Handle<FixedArray> array = instance->function_tables[i];
+ Handle<FixedArray> function_table = instance->function_tables[i];
+ Handle<FixedArray> signature_table = instance->signature_tables[i];
int table_size = static_cast<int>(table.values.size());
for (int j = 0; j < table_size; j++) {
WasmFunction& function = module_.functions[table.values[j]];
- array->set(j, Smi::FromInt(table.map.Find(function.sig)));
- array->set(j + table_size,
- *instance->function_code[function.func_index]);
+ signature_table->set(j, Smi::FromInt(table.map.Find(function.sig)));
+ function_table->set(j, *instance->function_code[function.func_index]);
}
}
}
+ uint32_t AddBytes(Vector<const byte> bytes) {
+ Handle<SeqOneByteString> old_bytes(
+ instance_object_->compiled_module()->module_bytes(), isolate_);
+ uint32_t old_size = static_cast<uint32_t>(old_bytes->length());
+ ScopedVector<byte> new_bytes(old_size + bytes.length());
+ memcpy(new_bytes.start(), old_bytes->GetChars(), old_size);
+ memcpy(new_bytes.start() + old_size, bytes.start(), bytes.length());
+ Handle<SeqOneByteString> new_bytes_str = Handle<SeqOneByteString>::cast(
+ isolate_->factory()->NewStringFromOneByte(new_bytes).ToHandleChecked());
+ instance_object_->compiled_module()->shared()->set_module_bytes(
+ *new_bytes_str);
+ return old_size;
+ }
+
WasmFunction* GetFunctionAt(int index) { return &module_.functions[index]; }
WasmInterpreter* interpreter() { return interpreter_; }
WasmExecutionMode execution_mode() { return execution_mode_; }
+ Isolate* isolate() { return isolate_; }
+ Handle<WasmInstanceObject> instance_object() { return instance_object_; }
private:
WasmExecutionMode execution_mode_;
WasmModule module_;
WasmInstance instance_;
Isolate* isolate_;
- v8::internal::AccountingAllocator allocator_;
uint32_t global_offset;
V8_ALIGNED(8) byte global_data[kMaxGlobalsSize]; // preallocated global data.
WasmInterpreter* interpreter_;
+ Handle<WasmInstanceObject> instance_object_;
- const WasmGlobal* AddGlobal(LocalType type) {
+ const WasmGlobal* AddGlobal(ValueType type) {
byte size = WasmOpcodes::MemSize(WasmOpcodes::MachineTypeFor(type));
global_offset = (global_offset + size - 1) & ~(size - 1); // align
module_.globals.push_back(
@@ -281,21 +315,43 @@ class TestingModule : public ModuleEnv {
CHECK_LT(global_offset, kMaxGlobalsSize);
return &module->globals.back();
}
+
+ Handle<WasmInstanceObject> InitInstanceObject() {
+ Handle<SeqOneByteString> empty_string = Handle<SeqOneByteString>::cast(
+ isolate_->factory()->NewStringFromOneByte({}).ToHandleChecked());
+ Handle<Managed<wasm::WasmModule>> module_wrapper =
+ Managed<wasm::WasmModule>::New(isolate_, &module_, false);
+ Handle<Script> script =
+ isolate_->factory()->NewScript(isolate_->factory()->empty_string());
+ script->set_type(Script::TYPE_WASM);
+ Handle<WasmSharedModuleData> shared_module_data =
+ WasmSharedModuleData::New(isolate_, module_wrapper, empty_string,
+ script, Handle<ByteArray>::null());
+ Handle<WasmCompiledModule> compiled_module =
+ WasmCompiledModule::New(isolate_, shared_module_data);
+ // Minimally initialize the compiled module such that IsWasmCompiledModule
+ // passes.
+ // If tests need more (correct) information, add it later.
+ compiled_module->set_min_mem_pages(0);
+ compiled_module->set_max_mem_pages(Smi::kMaxValue);
+ DCHECK(WasmCompiledModule::IsWasmCompiledModule(*compiled_module));
+ return WasmInstanceObject::New(isolate_, compiled_module);
+ }
};
inline void TestBuildingGraph(Zone* zone, JSGraph* jsgraph, ModuleEnv* module,
FunctionSig* sig,
SourcePositionTable* source_position_table,
const byte* start, const byte* end) {
- compiler::WasmGraphBuilder builder(zone, jsgraph, sig, source_position_table);
+ compiler::WasmGraphBuilder builder(module, zone, jsgraph, sig,
+ source_position_table);
DecodeResult result =
- BuildTFGraph(zone->allocator(), &builder, module, sig, start, end);
+ BuildTFGraph(zone->allocator(), &builder, sig, start, end);
if (result.failed()) {
if (!FLAG_trace_wasm_decoder) {
// Retry the compilation with the tracing flag on, to help in debugging.
FLAG_trace_wasm_decoder = true;
- result =
- BuildTFGraph(zone->allocator(), &builder, module, sig, start, end);
+ result = BuildTFGraph(zone->allocator(), &builder, sig, start, end);
}
ptrdiff_t pc = result.error_pc - result.start;
@@ -307,39 +363,34 @@ inline void TestBuildingGraph(Zone* zone, JSGraph* jsgraph, ModuleEnv* module,
FATAL(str.str().c_str());
}
builder.Int64LoweringForTesting();
- builder.SimdScalarLoweringForTesting();
+ if (!CpuFeatures::SupportsSimd128()) {
+ builder.SimdScalarLoweringForTesting();
+ }
}
-template <typename ReturnType>
-class WasmFunctionWrapper : public HandleAndZoneScope,
- private GraphAndBuilders {
+class WasmFunctionWrapper : private GraphAndBuilders {
public:
- WasmFunctionWrapper()
- : GraphAndBuilders(main_zone()),
- inner_code_node_(nullptr),
- signature_(nullptr) {
+ explicit WasmFunctionWrapper(Zone* zone, int num_params)
+ : GraphAndBuilders(zone), inner_code_node_(nullptr), signature_(nullptr) {
// One additional parameter for the pointer to the return value memory.
- Signature<MachineType>::Builder sig_builder(
- zone(), 1, WASM_RUNNER_MAX_NUM_PARAMETERS + 1);
+ Signature<MachineType>::Builder sig_builder(zone, 1, num_params + 1);
sig_builder.AddReturn(MachineType::Int32());
- for (int i = 0; i < WASM_RUNNER_MAX_NUM_PARAMETERS + 1; i++) {
+ for (int i = 0; i < num_params + 1; i++) {
sig_builder.AddParam(MachineType::Pointer());
}
signature_ = sig_builder.Build();
}
- void Init(CallDescriptor* descriptor, MachineType p0 = MachineType::None(),
- MachineType p1 = MachineType::None(),
- MachineType p2 = MachineType::None(),
- MachineType p3 = MachineType::None()) {
- // Create the TF graph for the wrapper. The wrapper always takes four
- // pointers as parameters, but may not pass the values of all pointers to
- // the actual test function.
+ void Init(CallDescriptor* descriptor, MachineType return_type,
+ Vector<MachineType> param_types) {
+ DCHECK_NOT_NULL(descriptor);
+ DCHECK_EQ(signature_->parameter_count(), param_types.length() + 1);
+
+ // Create the TF graph for the wrapper.
// Function, effect, and control.
- Node** parameters =
- zone()->template NewArray<Node*>(WASM_RUNNER_MAX_NUM_PARAMETERS + 3);
+ Node** parameters = zone()->NewArray<Node*>(param_types.length() + 3);
graph()->SetStart(graph()->NewNode(common()->Start(6)));
Node* effect = graph()->start();
int parameter_count = 0;
@@ -348,34 +399,12 @@ class WasmFunctionWrapper : public HandleAndZoneScope,
inner_code_node_ = graph()->NewNode(common()->Int32Constant(0));
parameters[parameter_count++] = inner_code_node_;
- if (p0 != MachineType::None()) {
- parameters[parameter_count] = graph()->NewNode(
- machine()->Load(p0),
- graph()->NewNode(common()->Parameter(0), graph()->start()),
- graph()->NewNode(common()->Int32Constant(0)), effect,
- graph()->start());
- effect = parameters[parameter_count++];
- }
- if (p1 != MachineType::None()) {
- parameters[parameter_count] = graph()->NewNode(
- machine()->Load(p1),
- graph()->NewNode(common()->Parameter(1), graph()->start()),
- graph()->NewNode(common()->Int32Constant(0)), effect,
- graph()->start());
- effect = parameters[parameter_count++];
- }
- if (p2 != MachineType::None()) {
- parameters[parameter_count] = graph()->NewNode(
- machine()->Load(p2),
- graph()->NewNode(common()->Parameter(2), graph()->start()),
- graph()->NewNode(common()->Int32Constant(0)), effect,
- graph()->start());
- effect = parameters[parameter_count++];
- }
- if (p3 != MachineType::None()) {
+ int param_idx = 0;
+ for (MachineType t : param_types) {
+ DCHECK_NE(MachineType::None(), t);
parameters[parameter_count] = graph()->NewNode(
- machine()->Load(p3),
- graph()->NewNode(common()->Parameter(3), graph()->start()),
+ machine()->Load(t),
+ graph()->NewNode(common()->Parameter(param_idx++), graph()->start()),
graph()->NewNode(common()->Int32Constant(0)), effect,
graph()->start());
effect = parameters[parameter_count++];
@@ -386,14 +415,15 @@ class WasmFunctionWrapper : public HandleAndZoneScope,
Node* call = graph()->NewNode(common()->Call(descriptor), parameter_count,
parameters);
- effect = graph()->NewNode(
- machine()->Store(
- StoreRepresentation(MachineTypeForC<ReturnType>().representation(),
- WriteBarrierKind::kNoWriteBarrier)),
- graph()->NewNode(common()->Parameter(WASM_RUNNER_MAX_NUM_PARAMETERS),
- graph()->start()),
- graph()->NewNode(common()->Int32Constant(0)), call, effect,
- graph()->start());
+ if (!return_type.IsNone()) {
+ effect = graph()->NewNode(
+ machine()->Store(StoreRepresentation(
+ return_type.representation(), WriteBarrierKind::kNoWriteBarrier)),
+ graph()->NewNode(common()->Parameter(param_types.length()),
+ graph()->start()),
+ graph()->NewNode(common()->Int32Constant(0)), call, effect,
+ graph()->start());
+ }
Node* zero = graph()->NewNode(common()->Int32Constant(0));
Node* r = graph()->NewNode(
common()->Return(), zero,
@@ -402,6 +432,15 @@ class WasmFunctionWrapper : public HandleAndZoneScope,
graph()->SetEnd(graph()->NewNode(common()->End(2), r, graph()->start()));
}
+ template <typename ReturnType, typename... ParamTypes>
+ void Init(CallDescriptor* descriptor) {
+ std::array<MachineType, sizeof...(ParamTypes)> param_machine_types{
+ {MachineTypeForC<ParamTypes>()...}};
+ Vector<MachineType> param_vec(param_machine_types.data(),
+ param_machine_types.size());
+ Init(descriptor, MachineTypeForC<ReturnType>(), param_vec);
+ }
+
void SetInnerCode(Handle<Code> code_handle) {
NodeProperties::ChangeOp(inner_code_node_,
common()->HeapConstant(code_handle));
@@ -415,12 +454,13 @@ class WasmFunctionWrapper : public HandleAndZoneScope,
Linkage::GetSimplifiedCDescriptor(zone(), signature_, true);
if (kPointerSize == 4) {
+ size_t num_params = signature_->parameter_count();
// One additional parameter for the pointer of the return value.
- Signature<MachineRepresentation>::Builder rep_builder(
- zone(), 1, WASM_RUNNER_MAX_NUM_PARAMETERS + 1);
+ Signature<MachineRepresentation>::Builder rep_builder(zone(), 1,
+ num_params + 1);
rep_builder.AddReturn(MachineRepresentation::kWord32);
- for (int i = 0; i < WASM_RUNNER_MAX_NUM_PARAMETERS + 1; i++) {
+ for (size_t i = 0; i < num_params + 1; i++) {
rep_builder.AddParam(MachineRepresentation::kWord32);
}
Int64Lowering r(graph(), machine(), common(), zone(),
@@ -452,129 +492,108 @@ class WasmFunctionWrapper : public HandleAndZoneScope,
Signature<MachineType>* signature_;
};
-// A helper for compiling WASM functions for testing. This class can create a
-// standalone function if {module} is NULL or a function within a
-// {TestingModule}. It contains the internal state for compilation (i.e.
-// TurboFan graph) and interpretation (by adding to the interpreter manually).
-class WasmFunctionCompiler : public HandleAndZoneScope,
- private GraphAndBuilders {
+// A helper for compiling WASM functions for testing.
+// It contains the internal state for compilation (i.e. TurboFan graph) and
+// interpretation (by adding to the interpreter manually).
+class WasmFunctionCompiler : private GraphAndBuilders {
public:
- explicit WasmFunctionCompiler(
- FunctionSig* sig, WasmExecutionMode mode,
- Vector<const char> debug_name = ArrayVector("<WASM UNNAMED>"))
- : GraphAndBuilders(main_zone()),
- execution_mode_(mode),
- jsgraph(this->isolate(), this->graph(), this->common(), nullptr,
- nullptr, this->machine()),
- sig(sig),
- descriptor_(nullptr),
- testing_module_(nullptr),
- debug_name_(debug_name),
- local_decls(main_zone(), sig),
- source_position_table_(this->graph()),
- interpreter_(nullptr) {
- // Create our own function.
- function_ = new WasmFunction();
- function_->sig = sig;
- function_->func_index = 0;
- function_->sig_index = 0;
- if (mode == kExecuteInterpreted) {
- interpreter_ = new WasmInterpreter(nullptr, zone()->allocator());
- int index = interpreter_->AddFunctionForTesting(function_);
- CHECK_EQ(0, index);
- }
- }
-
- explicit WasmFunctionCompiler(
- FunctionSig* sig, TestingModule* module,
- Vector<const char> debug_name = ArrayVector("<WASM UNNAMED>"))
- : GraphAndBuilders(main_zone()),
- execution_mode_(module->execution_mode()),
- jsgraph(this->isolate(), this->graph(), this->common(), nullptr,
- nullptr, this->machine()),
- sig(sig),
- descriptor_(nullptr),
- testing_module_(module),
- debug_name_(debug_name),
- local_decls(main_zone(), sig),
- source_position_table_(this->graph()),
- interpreter_(module->interpreter()) {
- // Get a new function from the testing module.
- int index = module->AddFunction(sig, Handle<Code>::null());
- function_ = testing_module_->GetFunctionAt(index);
- }
-
- ~WasmFunctionCompiler() {
- if (testing_module_) return; // testing module owns the below things.
- delete function_;
- if (interpreter_) delete interpreter_;
- }
-
- WasmExecutionMode execution_mode_;
- JSGraph jsgraph;
- FunctionSig* sig;
- // The call descriptor is initialized when the function is compiled.
- CallDescriptor* descriptor_;
- TestingModule* testing_module_;
- Vector<const char> debug_name_;
- WasmFunction* function_;
- LocalDeclEncoder local_decls;
- SourcePositionTable source_position_table_;
- WasmInterpreter* interpreter_;
-
- Isolate* isolate() { return main_isolate(); }
+ Isolate* isolate() { return testing_module_->isolate(); }
Graph* graph() const { return main_graph_; }
Zone* zone() const { return graph()->zone(); }
CommonOperatorBuilder* common() { return &main_common_; }
MachineOperatorBuilder* machine() { return &main_machine_; }
- void InitializeDescriptor() {
+ CallDescriptor* descriptor() {
if (descriptor_ == nullptr) {
- descriptor_ = testing_module_->GetWasmCallDescriptor(main_zone(), sig);
+ descriptor_ = testing_module_->GetWasmCallDescriptor(zone(), sig);
}
+ return descriptor_;
}
- CallDescriptor* descriptor() { return descriptor_; }
uint32_t function_index() { return function_->func_index; }
void Build(const byte* start, const byte* end) {
- // Build the TurboFan graph.
- local_decls.Prepend(main_zone(), &start, &end);
- TestBuildingGraph(main_zone(), &jsgraph, testing_module_, sig,
- &source_position_table_, start, end);
+ size_t locals_size = local_decls.Size();
+ size_t total_size = end - start + locals_size + 1;
+ byte* buffer = static_cast<byte*>(zone()->New(total_size));
+ // Prepend the local decls to the code.
+ local_decls.Emit(buffer);
+ // Emit the code.
+ memcpy(buffer + locals_size, start, end - start);
+ // Append an extra end opcode.
+ buffer[total_size - 1] = kExprEnd;
+
+ start = buffer;
+ end = buffer + total_size;
+
+ CHECK_GE(kMaxInt, end - start);
+ int len = static_cast<int>(end - start);
+ function_->code_start_offset =
+ testing_module_->AddBytes(Vector<const byte>(start, len));
+ function_->code_end_offset = function_->code_start_offset + len;
+
if (interpreter_) {
// Add the code to the interpreter.
CHECK(interpreter_->SetFunctionCodeForTesting(function_, start, end));
+ return;
}
+
+ // Build the TurboFan graph.
+ TestBuildingGraph(zone(), &jsgraph, testing_module_, sig,
+ &source_position_table_, start, end);
+ Handle<Code> code = Compile();
+ testing_module_->SetFunctionCode(function_index(), code);
}
- byte AllocateLocal(LocalType type) {
+ byte AllocateLocal(ValueType type) {
uint32_t index = local_decls.AddLocals(1, type);
byte result = static_cast<byte>(index);
DCHECK_EQ(index, result);
return result;
}
+ void SetSigIndex(int sig_index) { function_->sig_index = sig_index; }
+
+ private:
+ friend class WasmRunnerBase;
+
+ explicit WasmFunctionCompiler(Zone* zone, FunctionSig* sig,
+ TestingModule* module, const char* name)
+ : GraphAndBuilders(zone),
+ jsgraph(module->isolate(), this->graph(), this->common(), nullptr,
+ nullptr, this->machine()),
+ sig(sig),
+ descriptor_(nullptr),
+ testing_module_(module),
+ local_decls(zone, sig),
+ source_position_table_(this->graph()),
+ interpreter_(module->interpreter()) {
+ // Get a new function from the testing module.
+ int index = module->AddFunction(sig, Handle<Code>::null(), name);
+ function_ = testing_module_->GetFunctionAt(index);
+ }
+
Handle<Code> Compile() {
- InitializeDescriptor();
- CallDescriptor* desc = descriptor_;
+ CallDescriptor* desc = descriptor();
if (kPointerSize == 4) {
desc = testing_module_->GetI32WasmCallDescriptor(this->zone(), desc);
}
- CompilationInfo info(debug_name_, this->isolate(), this->zone(),
+ CompilationInfo info(CStrVector("wasm"), this->isolate(), this->zone(),
Code::ComputeFlags(Code::WASM_FUNCTION));
std::unique_ptr<CompilationJob> job(Pipeline::NewWasmCompilationJob(
- &info, graph(), desc, &source_position_table_));
+ &info, &jsgraph, desc, &source_position_table_, nullptr, false));
if (job->ExecuteJob() != CompilationJob::SUCCEEDED ||
job->FinalizeJob() != CompilationJob::SUCCEEDED)
return Handle<Code>::null();
Handle<Code> code = info.code();
- // Length is always 2, since usually <wasm_obj, func_index> is stored in
- // the deopt data. Here, we only store the function index.
+ // Deopt data holds <WeakCell<wasm_instance>, func_index>.
DCHECK(code->deoptimization_data() == nullptr ||
code->deoptimization_data()->length() == 0);
Handle<FixedArray> deopt_data =
isolate()->factory()->NewFixedArray(2, TENURED);
+ Handle<Object> weak_instance =
+ isolate()->factory()->NewWeakCell(testing_module_->instance_object());
+ deopt_data->set(0, *weak_instance);
deopt_data->set(1, Smi::FromInt(static_cast<int>(function_index())));
deopt_data->set_length(2);
code->set_deoptimization_data(*deopt_data);
@@ -589,76 +608,26 @@ class WasmFunctionCompiler : public HandleAndZoneScope,
return code;
}
- uint32_t CompileAndAdd(uint16_t sig_index = 0) {
- CHECK(testing_module_);
- function_->sig_index = sig_index;
- Handle<Code> code = Compile();
- testing_module_->SetFunctionCode(function_index(), code);
- return function_index();
- }
-
- // Set the context, such that e.g. runtime functions can be called.
- void SetModuleContext() {
- if (!testing_module_->instance->context.is_null()) {
- CHECK(testing_module_->instance->context.is_identical_to(
- main_isolate()->native_context()));
- return;
- }
- testing_module_->instance->context = main_isolate()->native_context();
- }
+ JSGraph jsgraph;
+ FunctionSig* sig;
+ // The call descriptor is initialized when the function is compiled.
+ CallDescriptor* descriptor_;
+ TestingModule* testing_module_;
+ Vector<const char> debug_name_;
+ WasmFunction* function_;
+ LocalDeclEncoder local_decls;
+ SourcePositionTable source_position_table_;
+ WasmInterpreter* interpreter_;
};
-// A helper class to build graphs from Wasm bytecode, generate machine
+// A helper class to build a module around Wasm bytecode, generate machine
// code, and run that code.
-template <typename ReturnType>
-class WasmRunner {
+class WasmRunnerBase : public HandleAndZoneScope {
public:
- WasmRunner(WasmExecutionMode execution_mode,
- MachineType p0 = MachineType::None(),
- MachineType p1 = MachineType::None(),
- MachineType p2 = MachineType::None(),
- MachineType p3 = MachineType::None())
- : zone(&allocator_, ZONE_NAME),
- compiled_(false),
- signature_(MachineTypeForC<ReturnType>() == MachineType::None() ? 0 : 1,
- GetParameterCount(p0, p1, p2, p3), storage_),
- compiler_(&signature_, execution_mode) {
- InitSigStorage(p0, p1, p2, p3);
- }
-
- WasmRunner(TestingModule* module, MachineType p0 = MachineType::None(),
- MachineType p1 = MachineType::None(),
- MachineType p2 = MachineType::None(),
- MachineType p3 = MachineType::None())
- : zone(&allocator_, ZONE_NAME),
- compiled_(false),
- signature_(MachineTypeForC<ReturnType>() == MachineType::None() ? 0 : 1,
- GetParameterCount(p0, p1, p2, p3), storage_),
- compiler_(&signature_, module),
- possible_nondeterminism_(false) {
- DCHECK(module);
- InitSigStorage(p0, p1, p2, p3);
- }
-
- void InitSigStorage(MachineType p0, MachineType p1, MachineType p2,
- MachineType p3) {
- int index = 0;
- MachineType ret = MachineTypeForC<ReturnType>();
- if (ret != MachineType::None()) {
- storage_[index++] = WasmOpcodes::LocalTypeFor(ret);
- }
- if (p0 != MachineType::None())
- storage_[index++] = WasmOpcodes::LocalTypeFor(p0);
- if (p1 != MachineType::None())
- storage_[index++] = WasmOpcodes::LocalTypeFor(p1);
- if (p2 != MachineType::None())
- storage_[index++] = WasmOpcodes::LocalTypeFor(p2);
- if (p3 != MachineType::None())
- storage_[index++] = WasmOpcodes::LocalTypeFor(p3);
-
- compiler_.InitializeDescriptor();
- wrapper_.Init(compiler_.descriptor(), p0, p1, p2, p3);
- }
+ explicit WasmRunnerBase(WasmExecutionMode execution_mode, int num_params)
+ : zone_(&allocator_, ZONE_NAME),
+ module_(&zone_, execution_mode),
+ wrapper_(&zone_, num_params) {}
// Builds a graph from the given Wasm code and generates the machine
// code and call wrapper for that graph. This method must not be called
@@ -666,83 +635,125 @@ class WasmRunner {
void Build(const byte* start, const byte* end) {
CHECK(!compiled_);
compiled_ = true;
- compiler_.Build(start, end);
+ functions_[0]->Build(start, end);
+ }
- if (!interpret()) {
- // Compile machine code and install it into the module.
- Handle<Code> code = compiler_.Compile();
+ // Resets the state for building the next function.
+ // The main function called will always be the first function.
+ template <typename ReturnType, typename... ParamTypes>
+ WasmFunctionCompiler& NewFunction(const char* name = nullptr) {
+ return NewFunction(CreateSig<ReturnType, ParamTypes...>(), name);
+ }
- if (compiler_.testing_module_) {
- // Update the table of function code in the module.
- compiler_.testing_module_->SetFunctionCode(
- compiler_.function_->func_index, code);
- }
+ // Resets the state for building the next function.
+ // The main function called will be the last generated function.
+ // Returns the index of the previously built function.
+ WasmFunctionCompiler& NewFunction(FunctionSig* sig,
+ const char* name = nullptr) {
+ functions_.emplace_back(
+ new WasmFunctionCompiler(&zone_, sig, &module_, name));
+ return *functions_.back();
+ }
- wrapper_.SetInnerCode(code);
- }
+ byte AllocateLocal(ValueType type) {
+ return functions_[0]->AllocateLocal(type);
}
- ReturnType Call() {
- if (interpret()) {
- return CallInterpreter(Vector<WasmVal>(nullptr, 0));
- } else {
- return Call(0, 0, 0, 0);
+ WasmFunction* function() { return functions_[0]->function_; }
+ WasmInterpreter* interpreter() { return functions_[0]->interpreter_; }
+ bool possible_nondeterminism() { return possible_nondeterminism_; }
+ TestingModule& module() { return module_; }
+ Zone* zone() { return &zone_; }
+
+ // Set the context, such that e.g. runtime functions can be called.
+ void SetModuleContext() {
+ if (!module_.instance->context.is_null()) {
+ CHECK(module_.instance->context.is_identical_to(
+ main_isolate()->native_context()));
+ return;
}
+ module_.instance->context = main_isolate()->native_context();
}
- template <typename P0>
- ReturnType Call(P0 p0) {
- if (interpret()) {
- WasmVal args[] = {WasmVal(p0)};
- return CallInterpreter(ArrayVector(args));
- } else {
- return Call(p0, 0, 0, 0);
+ private:
+ FunctionSig* CreateSig(MachineType return_type,
+ Vector<MachineType> param_types) {
+ int return_count = return_type.IsNone() ? 0 : 1;
+ int param_count = param_types.length();
+
+ // Allocate storage array in zone.
+ ValueType* sig_types =
+ zone_.NewArray<ValueType>(return_count + param_count);
+
+ // Convert machine types to local types, and check that there are no
+ // MachineType::None()'s in the parameters.
+ int idx = 0;
+ if (return_count) sig_types[idx++] = WasmOpcodes::ValueTypeFor(return_type);
+ for (MachineType param : param_types) {
+ CHECK_NE(MachineType::None(), param);
+ sig_types[idx++] = WasmOpcodes::ValueTypeFor(param);
}
+ return new (&zone_) FunctionSig(return_count, param_count, sig_types);
}
- template <typename P0, typename P1>
- ReturnType Call(P0 p0, P1 p1) {
- if (interpret()) {
- WasmVal args[] = {WasmVal(p0), WasmVal(p1)};
- return CallInterpreter(ArrayVector(args));
- } else {
- return Call(p0, p1, 0, 0);
- }
+ template <typename ReturnType, typename... ParamTypes>
+ FunctionSig* CreateSig() {
+ std::array<MachineType, sizeof...(ParamTypes)> param_machine_types{
+ {MachineTypeForC<ParamTypes>()...}};
+ Vector<MachineType> param_vec(param_machine_types.data(),
+ param_machine_types.size());
+ return CreateSig(MachineTypeForC<ReturnType>(), param_vec);
}
- template <typename P0, typename P1, typename P2>
- ReturnType Call(P0 p0, P1 p1, P2 p2) {
- if (interpret()) {
- WasmVal args[] = {WasmVal(p0), WasmVal(p1), WasmVal(p2)};
- return CallInterpreter(ArrayVector(args));
- } else {
- return Call(p0, p1, p2, 0);
+ protected:
+ v8::internal::AccountingAllocator allocator_;
+ Zone zone_;
+ TestingModule module_;
+ std::vector<std::unique_ptr<WasmFunctionCompiler>> functions_;
+ WasmFunctionWrapper wrapper_;
+ bool compiled_ = false;
+ bool possible_nondeterminism_ = false;
+
+ bool interpret() { return module_.execution_mode() == kExecuteInterpreted; }
+
+ public:
+ // This field has to be static. Otherwise, gcc complains about the using in
+ // the lambda context below.
+ static jmp_buf jump_buffer;
+};
+
+template <typename ReturnType, typename... ParamTypes>
+class WasmRunner : public WasmRunnerBase {
+ public:
+ explicit WasmRunner(WasmExecutionMode execution_mode,
+ const char* main_fn_name = "main")
+ : WasmRunnerBase(execution_mode, sizeof...(ParamTypes)) {
+ NewFunction<ReturnType, ParamTypes...>(main_fn_name);
+ if (!interpret()) {
+ wrapper_.Init<ReturnType, ParamTypes...>(functions_[0]->descriptor());
}
}
- template <typename P0, typename P1, typename P2, typename P3>
- ReturnType Call(P0 p0, P1 p1, P2 p2, P3 p3) {
- if (interpret()) {
- WasmVal args[] = {WasmVal(p0), WasmVal(p1), WasmVal(p2), WasmVal(p3)};
- return CallInterpreter(ArrayVector(args));
- } else {
- CodeRunner<int32_t> runner(CcTest::InitIsolateOnce(),
- wrapper_.GetWrapperCode(),
- wrapper_.signature());
- ReturnType return_value;
- int32_t result = runner.Call<void*, void*, void*, void*, void*>(
- &p0, &p1, &p2, &p3, &return_value);
- CHECK_EQ(WASM_WRAPPER_RETURN_VALUE, result);
- return return_value;
+ ReturnType Call(ParamTypes... p) {
+ DCHECK(compiled_);
+ if (interpret()) return CallInterpreter(p...);
+
+ // Use setjmp/longjmp to deal with traps in WebAssembly code.
+ ReturnType return_value = static_cast<ReturnType>(0xdeadbeefdeadbeef);
+ static int setjmp_ret;
+ setjmp_ret = setjmp(WasmRunnerBase::jump_buffer);
+ // setjmp returns 0 on the first return, 1 (passed to longjmp) after trap.
+ if (setjmp_ret == 0) {
+ DoCall(static_cast<void*>(&p)..., static_cast<void*>(&return_value));
}
+ return return_value;
}
- ReturnType CallInterpreter(Vector<WasmVal> args) {
- CHECK_EQ(args.length(),
- static_cast<int>(compiler_.function_->sig->parameter_count()));
+ ReturnType CallInterpreter(ParamTypes... p) {
WasmInterpreter::Thread* thread = interpreter()->GetThread(0);
thread->Reset();
- thread->PushFrame(compiler_.function_, args.start());
+ std::array<WasmVal, sizeof...(p)> args{{WasmVal(p)...}};
+ thread->PushFrame(function(), args.data());
if (thread->Run() == WasmInterpreter::FINISHED) {
WasmVal val = thread->GetReturnValue();
possible_nondeterminism_ |= thread->PossibleNondeterminism();
@@ -753,49 +764,59 @@ class WasmRunner {
return static_cast<ReturnType>(result);
} else {
// TODO(titzer): falling off end
- ReturnType val = 0;
- return val;
+ return ReturnType{0};
}
}
- byte AllocateLocal(LocalType type) { return compiler_.AllocateLocal(type); }
-
- WasmFunction* function() { return compiler_.function_; }
- WasmInterpreter* interpreter() { return compiler_.interpreter_; }
- bool possible_nondeterminism() { return possible_nondeterminism_; }
-
- protected:
- v8::internal::AccountingAllocator allocator_;
- Zone zone;
- bool compiled_;
- LocalType storage_[WASM_RUNNER_MAX_NUM_PARAMETERS];
- FunctionSig signature_;
- WasmFunctionCompiler compiler_;
- WasmFunctionWrapper<ReturnType> wrapper_;
- bool possible_nondeterminism_;
-
- bool interpret() { return compiler_.execution_mode_ == kExecuteInterpreted; }
-
- static size_t GetParameterCount(MachineType p0, MachineType p1,
- MachineType p2, MachineType p3) {
- if (p0 == MachineType::None()) return 0;
- if (p1 == MachineType::None()) return 1;
- if (p2 == MachineType::None()) return 2;
- if (p3 == MachineType::None()) return 3;
- return 4;
+ private:
+ // Don't inline this function. The setjmp above should be followed immediately
+ // by a call.
+ template <typename... Ptrs>
+ V8_NOINLINE void DoCall(Ptrs... ptrs) {
+ auto trap_callback = []() -> void {
+ set_trap_callback_for_testing(nullptr);
+ longjmp(WasmRunnerBase::jump_buffer, 1);
+ };
+ set_trap_callback_for_testing(trap_callback);
+
+ wrapper_.SetInnerCode(
+ module_.GetFunctionCode(functions_[0]->function_index()));
+ CodeRunner<int32_t> runner(CcTest::InitIsolateOnce(),
+ wrapper_.GetWrapperCode(), wrapper_.signature());
+ int32_t result = runner.Call(ptrs...);
+ // If we arrive here, no trap happened.
+ CHECK_EQ(WASM_WRAPPER_RETURN_VALUE, result);
}
};
+// Declare static variable.
+jmp_buf WasmRunnerBase::jump_buffer;
+
// A macro to define tests that run in different engine configurations.
-// Currently only supports compiled tests, but a future
-// RunWasmInterpreted_##name version will allow each test to also run in the
-// interpreter.
#define WASM_EXEC_TEST(name) \
void RunWasm_##name(WasmExecutionMode execution_mode); \
TEST(RunWasmCompiled_##name) { RunWasm_##name(kExecuteCompiled); } \
TEST(RunWasmInterpreted_##name) { RunWasm_##name(kExecuteInterpreted); } \
void RunWasm_##name(WasmExecutionMode execution_mode)
+#define WASM_EXEC_TEST_WITH_TRAP(name) \
+ void RunWasm_##name(WasmExecutionMode execution_mode); \
+ TEST(RunWasmCompiled_##name) { RunWasm_##name(kExecuteCompiled); } \
+ void RunWasm_##name(WasmExecutionMode execution_mode); \
+ TEST(RunWasmCompiledWithTrapIf_##name) { \
+ bool trap_if = FLAG_wasm_trap_if; \
+ FLAG_wasm_trap_if = true; \
+ RunWasm_##name(kExecuteCompiled); \
+ FLAG_wasm_trap_if = trap_if; \
+ } \
+ TEST(RunWasmInterpreted_##name) { RunWasm_##name(kExecuteInterpreted); } \
+ void RunWasm_##name(WasmExecutionMode execution_mode)
+
+#define WASM_EXEC_COMPILED_TEST(name) \
+ void RunWasm_##name(WasmExecutionMode execution_mode); \
+ TEST(RunWasmCompiled_##name) { RunWasm_##name(kExecuteCompiled); } \
+ void RunWasm_##name(WasmExecutionMode execution_mode)
+
} // namespace
#endif