| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/wasm-compiler.h" | 5 #include "src/compiler/wasm-compiler.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "src/isolate-inl.h" | 9 #include "src/isolate-inl.h" |
| 10 | 10 |
| (...skipping 2040 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2051 graph()->NewNode(machine->Word32Shl(), key, | 2051 graph()->NewNode(machine->Word32Shl(), key, |
| 2052 Int32Constant(kPointerSizeLog2)), | 2052 Int32Constant(kPointerSizeLog2)), |
| 2053 Uint32Constant(offset)), | 2053 Uint32Constant(offset)), |
| 2054 *effect_, *control_); | 2054 *effect_, *control_); |
| 2055 | 2055 |
| 2056 args[0] = load_code; | 2056 args[0] = load_code; |
| 2057 wasm::FunctionSig* sig = module_->GetSignature(index); | 2057 wasm::FunctionSig* sig = module_->GetSignature(index); |
| 2058 return BuildWasmCall(sig, args, position); | 2058 return BuildWasmCall(sig, args, position); |
| 2059 } | 2059 } |
| 2060 | 2060 |
| 2061 Node* WasmGraphBuilder::JITSingleFunction(Node* const base, Node* const length, | |
| 2062 Node* const index, | |
| 2063 const uint32_t sig_index, | |
| 2064 wasm::FunctionSig* const sig, | |
| 2065 wasm::WasmCodePosition position) { | |
| 2066 MachineOperatorBuilder* machine = jsgraph()->machine(); | |
| 2067 // Bounds check the memory access | |
| 2068 { | |
| 2069 Node* base_negative = | |
| 2070 graph()->NewNode(machine->Uint32LessThan(), base, Int32Constant(0)); | |
| 2071 trap_->AddTrapIfTrue(wasm::kTrapMemOutOfBounds, base_negative, position); | |
| 2072 | |
| 2073 Node* length_negative = graph()->NewNode(machine->Uint32LessThanOrEqual(), | |
| 2074 length, Int32Constant(0)); | |
| 2075 trap_->AddTrapIfTrue(wasm::kTrapFuncInvalid, length_negative, position); | |
| 2076 | |
| 2077 Node* in_bounds = graph()->NewNode( | |
| 2078 machine->Uint32LessThanOrEqual(), | |
| 2079 graph()->NewNode(machine->Int32Add(), base, length), MemSize(0)); | |
| 2080 trap_->AddTrapIfFalse(wasm::kTrapMemOutOfBounds, in_bounds, position); | |
| 2081 } | |
| 2082 | |
| 2083 // Bounds check the index. | |
| 2084 { | |
| 2085 // Assume only one table for now. | |
| 2086 DCHECK_LE(module_->instance->function_tables.size(), 1u); | |
| 2087 uint32_t table_size = | |
| 2088 module_->IsValidTable(0) ? module_->GetTable(0)->max_size : 0; | |
| 2089 if (table_size > 0) { | |
| 2090 // Bounds check against the table size. | |
| 2091 Node* size = Uint32Constant(table_size); | |
| 2092 Node* in_bounds = | |
| 2093 graph()->NewNode(machine->Uint32LessThan(), index, size); | |
| 2094 trap_->AddTrapIfFalse(wasm::kTrapInvalidIndex, in_bounds, position); | |
| 2095 } else { | |
| 2096 // No function table. Generate a trap and return a constant. | |
| 2097 trap_->AddTrapIfFalse(wasm::kTrapFuncInvalid, Int32Constant(0), position); | |
| 2098 return trap_->GetTrapValue(module_->GetSignature(sig_index)); | |
| 2099 } | |
| 2100 } | |
| 2101 | |
| 2102 const size_t runtime_input_params = 7; | |
| 2103 const size_t runtime_env_params = 5; | |
| 2104 | |
| 2105 Runtime::FunctionId f = Runtime::kJITSingleFunction; | |
| 2106 const Runtime::Function* fun = Runtime::FunctionForId(f); | |
| 2107 // CEntryStubConstant nodes have to be created and cached in the main | |
| 2108 // thread. At the moment this is only done for CEntryStubConstant(1). | |
| 2109 DCHECK_EQ(1, fun->result_size); | |
| 2110 const uint32_t return_count = static_cast<uint32_t>(sig->return_count()); | |
| 2111 const uint32_t parameter_count = | |
| 2112 static_cast<uint32_t>(sig->parameter_count()); | |
| 2113 | |
| 2114 const uint32_t inputs_size = runtime_input_params + runtime_env_params + | |
| 2115 return_count + parameter_count; | |
| 2116 Node** inputs = Buffer(inputs_size); | |
| 2117 inputs[0] = jsgraph()->CEntryStubConstant(fun->result_size); | |
| 2118 inputs[1] = BuildChangeUint32ToSmi(base); | |
| 2119 inputs[2] = BuildChangeUint32ToSmi(length); | |
| 2120 inputs[3] = BuildChangeUint32ToSmi(index); | |
| 2121 inputs[4] = FunctionTable(0); | |
| 2122 inputs[5] = Uint32Constant(sig_index); | |
| 2123 inputs[6] = BuildChangeUint32ToSmi(Uint32Constant(return_count)); | |
| 2124 | |
| 2125 // Pass in parameters and return types in to the runtime function | |
| 2126 // to allow it to regenerate signature | |
| 2127 for (uint32_t i = 0; i < return_count; ++i) { | |
| 2128 inputs[i + runtime_input_params] = BuildChangeUint32ToSmi( | |
| 2129 Uint32Constant(static_cast<int>(sig->GetReturn(i)))); | |
| 2130 } | |
| 2131 | |
| 2132 for (uint32_t i = 0; i < parameter_count; ++i) { | |
| 2133 inputs[i + runtime_input_params + return_count] = BuildChangeUint32ToSmi( | |
| 2134 Uint32Constant(static_cast<int>(sig->GetParam(i)))); | |
| 2135 } | |
| 2136 | |
| 2137 const uint32_t args_offset = inputs_size - runtime_env_params; | |
| 2138 inputs[args_offset] = jsgraph()->ExternalConstant( | |
| 2139 ExternalReference(f, jsgraph()->isolate())); // ref | |
| 2140 inputs[args_offset + 1] = jsgraph()->Int32Constant(args_offset - 1); // arity | |
| 2141 inputs[args_offset + 2] = | |
| 2142 HeapConstant(module_->instance->context); // context | |
| 2143 inputs[args_offset + 3] = *effect_; | |
| 2144 inputs[args_offset + 4] = *control_; | |
| 2145 | |
| 2146 // Use the module context to call the runtime. | |
| 2147 CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor( | |
| 2148 jsgraph()->zone(), f, args_offset - 1, Operator::kNoProperties, | |
| 2149 CallDescriptor::kNoFlags); | |
| 2150 | |
| 2151 Node* node = | |
| 2152 graph()->NewNode(jsgraph()->common()->Call(desc), inputs_size, inputs); | |
| 2153 *control_ = node; | |
| 2154 *effect_ = node; | |
| 2155 return node; | |
| 2156 } | |
| 2157 | |
| 2158 Node* WasmGraphBuilder::BuildI32Rol(Node* left, Node* right) { | 2061 Node* WasmGraphBuilder::BuildI32Rol(Node* left, Node* right) { |
| 2159 // Implement Rol by Ror since TurboFan does not have Rol opcode. | 2062 // Implement Rol by Ror since TurboFan does not have Rol opcode. |
| 2160 // TODO(weiliang): support Word32Rol opcode in TurboFan. | 2063 // TODO(weiliang): support Word32Rol opcode in TurboFan. |
| 2161 Int32Matcher m(right); | 2064 Int32Matcher m(right); |
| 2162 if (m.HasValue()) { | 2065 if (m.HasValue()) { |
| 2163 return Binop(wasm::kExprI32Ror, left, | 2066 return Binop(wasm::kExprI32Ror, left, |
| 2164 jsgraph()->Int32Constant(32 - m.Value())); | 2067 jsgraph()->Int32Constant(32 - m.Value())); |
| 2165 } else { | 2068 } else { |
| 2166 return Binop(wasm::kExprI32Ror, left, | 2069 return Binop(wasm::kExprI32Ror, left, |
| 2167 Binop(wasm::kExprI32Sub, jsgraph()->Int32Constant(32), right)); | 2070 Binop(wasm::kExprI32Sub, jsgraph()->Int32Constant(32), right)); |
| (...skipping 1253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3421 function_->code_start_offset), | 3324 function_->code_start_offset), |
| 3422 compile_ms); | 3325 compile_ms); |
| 3423 } | 3326 } |
| 3424 | 3327 |
| 3425 return code; | 3328 return code; |
| 3426 } | 3329 } |
| 3427 | 3330 |
| 3428 } // namespace compiler | 3331 } // namespace compiler |
| 3429 } // namespace internal | 3332 } // namespace internal |
| 3430 } // namespace v8 | 3333 } // namespace v8 |
| OLD | NEW |