| Index: src/compiler/wasm-compiler.cc
|
| diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc
|
| index 49a200aff0464b945ba0d6a6ea73d4aa085eb890..d6178b13deca772e6f31978a210591d27131d506 100644
|
| --- a/src/compiler/wasm-compiler.cc
|
| +++ b/src/compiler/wasm-compiler.cc
|
| @@ -2475,11 +2475,7 @@ Node* WasmGraphBuilder::ToJS(Node* node, wasm::ValueType type) {
|
| return BuildChangeInt32ToTagged(node);
|
| case wasm::kWasmS128:
|
| case wasm::kWasmI64:
|
| - // Throw a TypeError. The native context is good enough here because we
|
| - // only throw a TypeError.
|
| - return BuildCallToRuntime(Runtime::kWasmThrowTypeError, jsgraph(),
|
| - jsgraph()->isolate()->native_context(), nullptr,
|
| - 0, effect_, *control_);
|
| + UNREACHABLE();
|
| case wasm::kWasmF32:
|
| node = graph()->NewNode(jsgraph()->machine()->ChangeFloat32ToFloat64(),
|
| node);
|
| @@ -2641,11 +2637,7 @@ Node* WasmGraphBuilder::FromJS(Node* node, Node* context,
|
| }
|
| case wasm::kWasmS128:
|
| case wasm::kWasmI64:
|
| - // Throw a TypeError. The native context is good enough here because we
|
| - // only throw a TypeError.
|
| - return BuildCallToRuntime(Runtime::kWasmThrowTypeError, jsgraph(),
|
| - jsgraph()->isolate()->native_context(), nullptr,
|
| - 0, effect_, *control_);
|
| + UNREACHABLE();
|
| case wasm::kWasmF32:
|
| num = graph()->NewNode(jsgraph()->machine()->TruncateFloat64ToFloat32(),
|
| num);
|
| @@ -2740,22 +2732,59 @@ Node* WasmGraphBuilder::BuildHeapNumberValueIndexConstant() {
|
| return jsgraph()->IntPtrConstant(HeapNumber::kValueOffset - kHeapObjectTag);
|
| }
|
|
|
| +bool IsJSCompatible(wasm::ValueType type) {
|
| + return (type != wasm::kWasmI64) && (type != wasm::kWasmS128);
|
| +}
|
| +
|
| +bool HasJSCompatibleSignature(wasm::FunctionSig* sig) {
|
| + for (size_t i = 0; i < sig->parameter_count(); i++) {
|
| + if (!IsJSCompatible(sig->GetParam(i))) {
|
| + return false;
|
| + }
|
| + }
|
| + for (size_t i = 0; i < sig->return_count(); i++) {
|
| + if (!IsJSCompatible(sig->GetReturn(i))) {
|
| + return false;
|
| + }
|
| + }
|
| + return true;
|
| +}
|
| +
|
| void WasmGraphBuilder::BuildJSToWasmWrapper(Handle<Code> wasm_code,
|
| wasm::FunctionSig* sig) {
|
| int wasm_count = static_cast<int>(sig->parameter_count());
|
| - int param_count;
|
| - if (jsgraph()->machine()->Is64()) {
|
| - param_count = static_cast<int>(sig->parameter_count());
|
| - } else {
|
| - param_count = Int64Lowering::GetParameterCountAfterLowering(sig);
|
| - }
|
| - int count = param_count + 3;
|
| + int count = wasm_count + 3;
|
| Node** args = Buffer(count);
|
|
|
| // Build the start and the JS parameter nodes.
|
| - Node* start = Start(param_count + 5);
|
| + Node* start = Start(wasm_count + 5);
|
| *control_ = start;
|
| *effect_ = start;
|
| +
|
| + if (!HasJSCompatibleSignature(sig_)) {
|
| + // Throw a TypeError. The native context is good enough here because we
|
| + // only throw a TypeError.
|
| + BuildCallToRuntime(Runtime::kWasmThrowTypeError, jsgraph(),
|
| + jsgraph()->isolate()->native_context(), nullptr, 0,
|
| + effect_, *control_);
|
| +
|
| + // Add a dummy call to the wasm function so that the generated wrapper
|
| + // contains a reference to the wrapped wasm function. Without this reference
|
| + // the wasm function could not be re-imported into another wasm module.
|
| + int pos = 0;
|
| + args[pos++] = HeapConstant(wasm_code);
|
| + args[pos++] = *effect_;
|
| + args[pos++] = *control_;
|
| +
|
| + // We only need a dummy call descriptor.
|
| + wasm::FunctionSig::Builder dummy_sig_builder(jsgraph()->zone(), 0, 0);
|
| + CallDescriptor* desc = wasm::ModuleEnv::GetWasmCallDescriptor(
|
| + jsgraph()->zone(), dummy_sig_builder.Build());
|
| + *effect_ = graph()->NewNode(jsgraph()->common()->Call(desc), pos, args);
|
| + Return(jsgraph()->UndefinedConstant());
|
| + return;
|
| + }
|
| +
|
| // Create the context parameter
|
| Node* context = graph()->NewNode(
|
| jsgraph()->common()->Parameter(
|
| @@ -2770,11 +2799,6 @@ void WasmGraphBuilder::BuildJSToWasmWrapper(Handle<Code> wasm_code,
|
| Node* param = Param(i + 1);
|
| Node* wasm_param = FromJS(param, context, sig->GetParam(i));
|
| args[pos++] = wasm_param;
|
| - if (jsgraph()->machine()->Is32() && sig->GetParam(i) == wasm::kWasmI64) {
|
| - // We make up the high word with SAR to get the proper sign extension.
|
| - args[pos++] = graph()->NewNode(jsgraph()->machine()->Word32Sar(),
|
| - wasm_param, jsgraph()->Int32Constant(31));
|
| - }
|
| }
|
|
|
| args[pos++] = *effect_;
|
| @@ -2783,18 +2807,10 @@ void WasmGraphBuilder::BuildJSToWasmWrapper(Handle<Code> wasm_code,
|
| // Call the WASM code.
|
| CallDescriptor* desc =
|
| wasm::ModuleEnv::GetWasmCallDescriptor(jsgraph()->zone(), sig);
|
| - if (jsgraph()->machine()->Is32()) {
|
| - desc = wasm::ModuleEnv::GetI32WasmCallDescriptor(jsgraph()->zone(), desc);
|
| - }
|
| +
|
| Node* call = graph()->NewNode(jsgraph()->common()->Call(desc), count, args);
|
| *effect_ = call;
|
| Node* retval = call;
|
| - if (jsgraph()->machine()->Is32() && sig->return_count() > 0 &&
|
| - sig->GetReturn(0) == wasm::kWasmI64) {
|
| - // The return values comes as two values, we pick the low word.
|
| - retval = graph()->NewNode(jsgraph()->common()->Projection(0), retval,
|
| - graph()->start());
|
| - }
|
| Node* jsval = ToJS(
|
| retval, sig->return_count() == 0 ? wasm::kWasmStmt : sig->GetReturn());
|
| Return(jsval);
|
| @@ -2807,11 +2823,6 @@ int WasmGraphBuilder::AddParameterNodes(Node** args, int pos, int param_count,
|
| for (int i = 0; i < param_count; ++i) {
|
| Node* param = Param(param_index++);
|
| args[pos++] = ToJS(param, sig->GetParam(i));
|
| - if (jsgraph()->machine()->Is32() && sig->GetParam(i) == wasm::kWasmI64) {
|
| - // On 32 bit platforms we have to skip the high word of int64
|
| - // parameters.
|
| - param_index++;
|
| - }
|
| }
|
| return pos;
|
| }
|
| @@ -2821,19 +2832,23 @@ void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSReceiver> target,
|
| DCHECK(target->IsCallable());
|
|
|
| int wasm_count = static_cast<int>(sig->parameter_count());
|
| - int param_count;
|
| - if (jsgraph()->machine()->Is64()) {
|
| - param_count = wasm_count;
|
| - } else {
|
| - param_count = Int64Lowering::GetParameterCountAfterLowering(sig);
|
| - }
|
|
|
| // Build the start and the parameter nodes.
|
| Isolate* isolate = jsgraph()->isolate();
|
| CallDescriptor* desc;
|
| - Node* start = Start(param_count + 3);
|
| + Node* start = Start(wasm_count + 3);
|
| *effect_ = start;
|
| *control_ = start;
|
| +
|
| + if (!HasJSCompatibleSignature(sig_)) {
|
| + // Throw a TypeError. The native context is good enough here because we
|
| + // only throw a TypeError.
|
| + Return(BuildCallToRuntime(Runtime::kWasmThrowTypeError, jsgraph(),
|
| + jsgraph()->isolate()->native_context(), nullptr,
|
| + 0, effect_, *control_));
|
| + return;
|
| + }
|
| +
|
| Node** args = Buffer(wasm_count + 7);
|
|
|
| Node* call;
|
|
|