| Index: src/interpreter/interpreter-intrinsics.cc
|
| diff --git a/src/interpreter/interpreter-intrinsics.cc b/src/interpreter/interpreter-intrinsics.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..6d9917de4faca4988ba71c0847c15a5a07e4eabc
|
| --- /dev/null
|
| +++ b/src/interpreter/interpreter-intrinsics.cc
|
| @@ -0,0 +1,159 @@
|
| +// Copyright 2015 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/interpreter/interpreter-intrinsics.h"
|
| +
|
| +namespace v8 {
|
| +namespace internal {
|
| +namespace interpreter {
|
| +
|
| +using compiler::Node;
|
| +
|
| +#define __ assembler_->
|
| +
|
| +IntrinsicsHelper::IntrinsicsHelper(InterpreterAssembler* assembler)
|
| + : assembler_(assembler) {}
|
| +
|
| +bool IntrinsicsHelper::IsSupported(Runtime::FunctionId function_id) {
|
| + switch (function_id) {
|
| +#define SUPPORTED(name, lower_case, count) case Runtime::kInline##name:
|
| + INTRINSICS_LIST(SUPPORTED)
|
| + return true;
|
| +#undef SUPPORTED
|
| + default:
|
| + return false;
|
| + }
|
| +}
|
| +
|
| +Node* IntrinsicsHelper::InvokeIntrinsic(Node* function_id, Node* context,
|
| + Node* first_arg_reg, Node* arg_count) {
|
| + InterpreterAssembler::Label abort(assembler_), end(assembler_);
|
| + InterpreterAssembler::Variable result(assembler_,
|
| + MachineRepresentation::kTagged);
|
| +
|
| +#define MAKE_LABEL(name, lower_case, count) \
|
| + InterpreterAssembler::Label lower_case(assembler_);
|
| + INTRINSICS_LIST(MAKE_LABEL)
|
| +#undef MAKE_LABEL
|
| +
|
| +#define LABEL_POINTER(name, lower_case, count) &lower_case,
|
| + InterpreterAssembler::Label* labels[] = {INTRINSICS_LIST(LABEL_POINTER)};
|
| +#undef LABEL_POINTER
|
| +
|
| +#define CASE(name, lower_case, count) \
|
| + static_cast<int32_t>(Runtime::kInline##name),
|
| + int32_t cases[] = {INTRINSICS_LIST(CASE)};
|
| +#undef CASE
|
| +
|
| + __ Switch(function_id, &abort, cases, labels, arraysize(cases));
|
| +#define HANDLE_CASE(name, lower_case, expected_arg_count) \
|
| + __ Bind(&lower_case); \
|
| + if (FLAG_debug_code) { \
|
| + AbortIfArgCountMismatch(expected_arg_count, arg_count); \
|
| + } \
|
| + result.Bind(name(first_arg_reg)); \
|
| + __ Goto(&end);
|
| + INTRINSICS_LIST(HANDLE_CASE)
|
| +#undef HANDLE_CASE
|
| +
|
| + __ Bind(&abort);
|
| + __ Abort(BailoutReason::kUnexpectedFunctionIDForInvokeIntrinsic);
|
| + result.Bind(__ UndefinedConstant());
|
| + __ Goto(&end);
|
| +
|
| + __ Bind(&end);
|
| + return result.value();
|
| +}
|
| +
|
| +Node* IntrinsicsHelper::CompareInstanceType(Node* map, int type,
|
| + InstanceTypeCompareMode mode) {
|
| + InterpreterAssembler::Variable return_value(assembler_,
|
| + MachineRepresentation::kTagged);
|
| + Node* instance_type = __ LoadInstanceType(map);
|
| +
|
| + InterpreterAssembler::Label if_true(assembler_), if_false(assembler_),
|
| + end(assembler_);
|
| + Node* condition;
|
| + if (mode == kInstanceTypeEqual) {
|
| + condition = __ Word32Equal(instance_type, __ Int32Constant(type));
|
| + } else {
|
| + DCHECK(mode == kInstanceTypeGreaterThanOrEqual);
|
| + condition =
|
| + __ Int32GreaterThanOrEqual(instance_type, __ Int32Constant(type));
|
| + }
|
| + __ Branch(condition, &if_true, &if_false);
|
| +
|
| + __ Bind(&if_true);
|
| + return_value.Bind(__ BooleanConstant(true));
|
| + __ Goto(&end);
|
| +
|
| + __ Bind(&if_false);
|
| + return_value.Bind(__ BooleanConstant(false));
|
| + __ Goto(&end);
|
| +
|
| + __ Bind(&end);
|
| + return return_value.value();
|
| +}
|
| +
|
| +Node* IntrinsicsHelper::IsJSReceiver(Node* input) {
|
| + InterpreterAssembler::Variable return_value(assembler_,
|
| + MachineRepresentation::kTagged);
|
| +
|
| + InterpreterAssembler::Label if_smi(assembler_), if_not_smi(assembler_),
|
| + end(assembler_);
|
| + Node* arg = __ LoadRegister(input);
|
| +
|
| + __ Branch(__ WordIsSmi(arg), &if_smi, &if_not_smi);
|
| + __ Bind(&if_smi);
|
| + return_value.Bind(__ BooleanConstant(false));
|
| + __ Goto(&end);
|
| +
|
| + __ Bind(&if_not_smi);
|
| + STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
|
| + return_value.Bind(CompareInstanceType(arg, FIRST_JS_RECEIVER_TYPE,
|
| + kInstanceTypeGreaterThanOrEqual));
|
| + __ Goto(&end);
|
| +
|
| + __ Bind(&end);
|
| + return return_value.value();
|
| +}
|
| +
|
| +Node* IntrinsicsHelper::IsArray(Node* input) {
|
| + InterpreterAssembler::Variable return_value(assembler_,
|
| + MachineRepresentation::kTagged);
|
| +
|
| + InterpreterAssembler::Label if_smi(assembler_), if_not_smi(assembler_),
|
| + end(assembler_);
|
| + Node* arg = __ LoadRegister(input);
|
| +
|
| + __ Branch(__ WordIsSmi(arg), &if_smi, &if_not_smi);
|
| + __ Bind(&if_smi);
|
| + return_value.Bind(__ BooleanConstant(false));
|
| + __ Goto(&end);
|
| +
|
| + __ Bind(&if_not_smi);
|
| + return_value.Bind(
|
| + CompareInstanceType(arg, JS_ARRAY_TYPE, kInstanceTypeEqual));
|
| + __ Goto(&end);
|
| +
|
| + __ Bind(&end);
|
| + return return_value.value();
|
| +}
|
| +
|
| +void IntrinsicsHelper::AbortIfArgCountMismatch(int expected, Node* actual) {
|
| + InterpreterAssembler::Label match(assembler_), mismatch(assembler_),
|
| + end(assembler_);
|
| + Node* comparison = __ Word32Equal(actual, __ Int32Constant(expected));
|
| + __ Branch(comparison, &match, &mismatch);
|
| + __ Bind(&mismatch);
|
| + __ Abort(kWrongArgumentCountForInvokeIntrinsic);
|
| + __ Goto(&end);
|
| + __ Bind(&match);
|
| + __ Goto(&end);
|
| + __ Bind(&end);
|
| +}
|
| +
|
| +} // namespace interpreter
|
| +} // namespace internal
|
| +} // namespace v8
|
|
|