| 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/api-natives.h" | 5 #include "src/api-natives.h" |
| 6 #include "src/api.h" | 6 #include "src/api.h" |
| 7 #include "src/asmjs/asm-js.h" | 7 #include "src/asmjs/asm-js.h" |
| 8 #include "src/asmjs/asm-typer.h" | 8 #include "src/asmjs/asm-typer.h" |
| 9 #include "src/asmjs/asm-wasm-builder.h" | 9 #include "src/asmjs/asm-wasm-builder.h" |
| 10 #include "src/assert-scope.h" | 10 #include "src/assert-scope.h" |
| 11 #include "src/ast/ast.h" | 11 #include "src/ast/ast.h" |
| 12 #include "src/execution.h" | 12 #include "src/execution.h" |
| 13 #include "src/factory.h" | 13 #include "src/factory.h" |
| 14 #include "src/handles.h" | 14 #include "src/handles.h" |
| 15 #include "src/isolate.h" | 15 #include "src/isolate.h" |
| 16 #include "src/objects.h" | 16 #include "src/objects.h" |
| 17 #include "src/parsing/parse-info.h" | 17 #include "src/parsing/parse-info.h" |
| 18 | 18 |
| 19 #include "src/wasm/module-decoder.h" | 19 #include "src/wasm/module-decoder.h" |
| 20 #include "src/wasm/wasm-js.h" | 20 #include "src/wasm/wasm-js.h" |
| 21 #include "src/wasm/wasm-module.h" | 21 #include "src/wasm/wasm-module.h" |
| 22 #include "src/wasm/wasm-objects.h" |
| 22 #include "src/wasm/wasm-result.h" | 23 #include "src/wasm/wasm-result.h" |
| 23 | 24 |
| 24 typedef uint8_t byte; | 25 typedef uint8_t byte; |
| 25 | 26 |
| 26 using v8::internal::wasm::ErrorThrower; | 27 using v8::internal::wasm::ErrorThrower; |
| 27 | 28 |
| 28 namespace v8 { | 29 namespace v8 { |
| 29 | 30 |
| 30 static const int kWasmTableArrayFieldIndex = 0; | |
| 31 static const int kWasmTableMaximumFieldIndex = 1; | |
| 32 static const int kWasmTableDispatchTablesFieldIndex = 2; | |
| 33 | |
| 34 enum WasmMemoryObjectData { | 31 enum WasmMemoryObjectData { |
| 35 kWasmMemoryBuffer, | 32 kWasmMemoryBuffer, |
| 36 kWasmMemoryMaximum, | 33 kWasmMemoryMaximum, |
| 37 kWasmMemoryInstanceObject | 34 kWasmMemoryInstanceObject |
| 38 }; | 35 }; |
| 39 | 36 |
| 40 enum WasmInternalFieldCountData { | |
| 41 kWasmTableInternalFieldCount = 3, | |
| 42 kWasmMemoryInternalFieldCount = 3 | |
| 43 }; | |
| 44 | |
| 45 namespace { | 37 namespace { |
| 46 i::Handle<i::String> v8_str(i::Isolate* isolate, const char* str) { | 38 i::Handle<i::String> v8_str(i::Isolate* isolate, const char* str) { |
| 47 return isolate->factory()->NewStringFromAsciiChecked(str); | 39 return isolate->factory()->NewStringFromAsciiChecked(str); |
| 48 } | 40 } |
| 49 Local<String> v8_str(Isolate* isolate, const char* str) { | 41 Local<String> v8_str(Isolate* isolate, const char* str) { |
| 50 return Utils::ToLocal(v8_str(reinterpret_cast<i::Isolate*>(isolate), str)); | 42 return Utils::ToLocal(v8_str(reinterpret_cast<i::Isolate*>(isolate), str)); |
| 51 } | 43 } |
| 52 | 44 |
| 53 struct RawBuffer { | 45 struct RawBuffer { |
| 54 const byte* start; | 46 const byte* start; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 if (start == nullptr || end == start) { | 78 if (start == nullptr || end == start) { |
| 87 thrower->TypeError("ArrayBuffer argument is empty"); | 79 thrower->TypeError("ArrayBuffer argument is empty"); |
| 88 } | 80 } |
| 89 } else { | 81 } else { |
| 90 thrower->TypeError("Argument 0 must be an ArrayBuffer or Uint8Array"); | 82 thrower->TypeError("Argument 0 must be an ArrayBuffer or Uint8Array"); |
| 91 } | 83 } |
| 92 | 84 |
| 93 return {start, end}; | 85 return {start, end}; |
| 94 } | 86 } |
| 95 | 87 |
| 96 static i::MaybeHandle<i::JSObject> CreateModuleObject( | 88 static i::MaybeHandle<i::WasmModuleObject> CreateModuleObject( |
| 97 v8::Isolate* isolate, const v8::Local<v8::Value> source, | 89 v8::Isolate* isolate, const v8::Local<v8::Value> source, |
| 98 ErrorThrower* thrower) { | 90 ErrorThrower* thrower) { |
| 99 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 91 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
| 100 i::MaybeHandle<i::JSObject> nothing; | 92 i::MaybeHandle<i::JSObject> nothing; |
| 101 | 93 |
| 102 RawBuffer buffer = GetRawBufferSource(source, thrower); | 94 RawBuffer buffer = GetRawBufferSource(source, thrower); |
| 103 if (buffer.start == nullptr) return i::MaybeHandle<i::JSObject>(); | 95 if (buffer.start == nullptr) return i::MaybeHandle<i::WasmModuleObject>(); |
| 104 | 96 |
| 105 DCHECK(source->IsArrayBuffer() || source->IsTypedArray()); | 97 DCHECK(source->IsArrayBuffer() || source->IsTypedArray()); |
| 106 return i::wasm::CreateModuleObjectFromBytes( | 98 return i::wasm::CreateModuleObjectFromBytes( |
| 107 i_isolate, buffer.start, buffer.end, thrower, i::wasm::kWasmOrigin, | 99 i_isolate, buffer.start, buffer.end, thrower, i::wasm::kWasmOrigin, |
| 108 i::Handle<i::Script>::null(), nullptr, nullptr); | 100 i::Handle<i::Script>::null(), nullptr, nullptr); |
| 109 } | 101 } |
| 110 | 102 |
| 111 static bool ValidateModule(v8::Isolate* isolate, | 103 static bool ValidateModule(v8::Isolate* isolate, |
| 112 const v8::Local<v8::Value> source, | 104 const v8::Local<v8::Value> source, |
| 113 ErrorThrower* thrower) { | 105 ErrorThrower* thrower) { |
| 114 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 106 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
| 115 i::MaybeHandle<i::JSObject> nothing; | 107 i::MaybeHandle<i::JSObject> nothing; |
| 116 | 108 |
| 117 RawBuffer buffer = GetRawBufferSource(source, thrower); | 109 RawBuffer buffer = GetRawBufferSource(source, thrower); |
| 118 if (buffer.start == nullptr) return false; | 110 if (buffer.start == nullptr) return false; |
| 119 | 111 |
| 120 DCHECK(source->IsArrayBuffer() || source->IsTypedArray()); | 112 DCHECK(source->IsArrayBuffer() || source->IsTypedArray()); |
| 121 return i::wasm::ValidateModuleBytes(i_isolate, buffer.start, buffer.end, | 113 return i::wasm::ValidateModuleBytes(i_isolate, buffer.start, buffer.end, |
| 122 thrower, | 114 thrower, |
| 123 i::wasm::ModuleOrigin::kWasmOrigin); | 115 i::wasm::ModuleOrigin::kWasmOrigin); |
| 124 } | 116 } |
| 125 | 117 |
| 126 bool BrandCheck(Isolate* isolate, i::Handle<i::Object> value, | 118 static bool BrandCheck(Isolate* isolate, i::Handle<i::Object> value, |
| 127 i::Handle<i::Symbol> sym, const char* msg) { | 119 i::Handle<i::Symbol> sym, const char* msg) { |
| 128 if (value->IsJSObject()) { | 120 if (value->IsJSObject()) { |
| 129 i::Handle<i::JSObject> object = i::Handle<i::JSObject>::cast(value); | 121 i::Handle<i::JSObject> object = i::Handle<i::JSObject>::cast(value); |
| 130 Maybe<bool> has_brand = i::JSObject::HasOwnProperty(object, sym); | 122 Maybe<bool> has_brand = i::JSObject::HasOwnProperty(object, sym); |
| 131 if (has_brand.IsNothing()) return false; | 123 if (has_brand.IsNothing()) return false; |
| 132 if (has_brand.ToChecked()) return true; | 124 if (has_brand.ToChecked()) return true; |
| 133 } | 125 } |
| 134 v8::Local<v8::Value> e = v8::Exception::TypeError(v8_str(isolate, msg)); | 126 v8::Local<v8::Value> e = v8::Exception::TypeError(v8_str(isolate, msg)); |
| 135 isolate->ThrowException(e); | 127 isolate->ThrowException(e); |
| 136 return false; | 128 return false; |
| 137 } | 129 } |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 if (args.Length() > 1 && args[1]->IsObject()) { | 218 if (args.Length() > 1 && args[1]->IsObject()) { |
| 227 Local<Object> obj = Local<Object>::Cast(args[1]); | 219 Local<Object> obj = Local<Object>::Cast(args[1]); |
| 228 ffi = i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj)); | 220 ffi = i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj)); |
| 229 } | 221 } |
| 230 | 222 |
| 231 i::Handle<i::JSArrayBuffer> memory = i::Handle<i::JSArrayBuffer>::null(); | 223 i::Handle<i::JSArrayBuffer> memory = i::Handle<i::JSArrayBuffer>::null(); |
| 232 if (args.Length() > 2 && args[2]->IsObject()) { | 224 if (args.Length() > 2 && args[2]->IsObject()) { |
| 233 Local<Object> obj = Local<Object>::Cast(args[2]); | 225 Local<Object> obj = Local<Object>::Cast(args[2]); |
| 234 i::Handle<i::Object> mem_obj = v8::Utils::OpenHandle(*obj); | 226 i::Handle<i::Object> mem_obj = v8::Utils::OpenHandle(*obj); |
| 235 if (i::WasmJs::IsWasmMemoryObject(i_isolate, mem_obj)) { | 227 if (i::WasmJs::IsWasmMemoryObject(i_isolate, mem_obj)) { |
| 236 memory = i::WasmJs::GetWasmMemoryArrayBuffer(i_isolate, mem_obj); | 228 memory = i::Handle<i::JSArrayBuffer>( |
| 229 i::Handle<i::WasmMemoryObject>::cast(mem_obj)->get_buffer(), |
| 230 i_isolate); |
| 237 } else { | 231 } else { |
| 238 thrower.TypeError("Argument 2 must be a WebAssembly.Memory"); | 232 thrower.TypeError("Argument 2 must be a WebAssembly.Memory"); |
| 239 } | 233 } |
| 240 } | 234 } |
| 241 i::MaybeHandle<i::JSObject> instance = | 235 i::MaybeHandle<i::JSObject> instance = |
| 242 i::wasm::WasmModule::Instantiate(i_isolate, &thrower, i_obj, ffi, memory); | 236 i::wasm::WasmModule::Instantiate(i_isolate, &thrower, i_obj, ffi, memory); |
| 243 if (instance.is_null()) { | 237 if (instance.is_null()) { |
| 244 if (!thrower.error()) thrower.RuntimeError("Could not instantiate module"); | 238 if (!thrower.error()) thrower.RuntimeError("Could not instantiate module"); |
| 245 return; | 239 return; |
| 246 } | 240 } |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 | 312 |
| 319 if (has_maximum.IsNothing()) { | 313 if (has_maximum.IsNothing()) { |
| 320 // There has been an exception, just return. | 314 // There has been an exception, just return. |
| 321 return; | 315 return; |
| 322 } | 316 } |
| 323 if (has_maximum.FromJust()) { | 317 if (has_maximum.FromJust()) { |
| 324 if (!GetIntegerProperty(isolate, &thrower, context, descriptor, maximum_key, | 318 if (!GetIntegerProperty(isolate, &thrower, context, descriptor, maximum_key, |
| 325 &maximum, initial, max_table_size)) { | 319 &maximum, initial, max_table_size)) { |
| 326 return; | 320 return; |
| 327 } | 321 } |
| 322 } else { |
| 323 maximum = static_cast<int>(i::wasm::WasmModule::kV8MaxTableSize); |
| 328 } | 324 } |
| 329 | 325 |
| 330 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 326 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
| 331 i::Handle<i::FixedArray> fixed_array; | 327 i::Handle<i::FixedArray> fixed_array; |
| 332 i::Handle<i::JSObject> table_obj = i::WasmJs::CreateWasmTableObject( | 328 i::Handle<i::JSObject> table_obj = |
| 333 i_isolate, initial, has_maximum.FromJust(), maximum, &fixed_array); | 329 i::WasmTableObject::New(i_isolate, initial, maximum, &fixed_array); |
| 334 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); | 330 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); |
| 335 return_value.Set(Utils::ToLocal(table_obj)); | 331 return_value.Set(Utils::ToLocal(table_obj)); |
| 336 } | 332 } |
| 337 | 333 |
| 338 void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) { | 334 void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 339 v8::Isolate* isolate = args.GetIsolate(); | 335 v8::Isolate* isolate = args.GetIsolate(); |
| 340 HandleScope scope(isolate); | 336 HandleScope scope(isolate); |
| 341 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), | 337 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), |
| 342 "WebAssembly.Module()"); | 338 "WebAssembly.Module()"); |
| 343 if (args.Length() < 1 || !args[0]->IsObject()) { | 339 if (args.Length() < 1 || !args[0]->IsObject()) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 367 return; | 363 return; |
| 368 } | 364 } |
| 369 } | 365 } |
| 370 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 366 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
| 371 i::Handle<i::JSArrayBuffer> buffer = | 367 i::Handle<i::JSArrayBuffer> buffer = |
| 372 i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kNotShared); | 368 i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kNotShared); |
| 373 size_t size = static_cast<size_t>(i::wasm::WasmModule::kPageSize) * | 369 size_t size = static_cast<size_t>(i::wasm::WasmModule::kPageSize) * |
| 374 static_cast<size_t>(initial); | 370 static_cast<size_t>(initial); |
| 375 i::JSArrayBuffer::SetupAllocatingData(buffer, i_isolate, size); | 371 i::JSArrayBuffer::SetupAllocatingData(buffer, i_isolate, size); |
| 376 | 372 |
| 377 i::Handle<i::JSObject> memory_obj = i::WasmJs::CreateWasmMemoryObject( | 373 i::Handle<i::JSObject> memory_obj = i::WasmMemoryObject::New( |
| 378 i_isolate, buffer, has_maximum.FromJust(), maximum); | 374 i_isolate, buffer, has_maximum.FromJust() ? maximum : -1); |
| 379 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); | 375 args.GetReturnValue().Set(Utils::ToLocal(memory_obj)); |
| 380 return_value.Set(Utils::ToLocal(memory_obj)); | |
| 381 } | 376 } |
| 382 | 377 |
| 383 void WebAssemblyTableGetLength( | 378 void WebAssemblyTableGetLength( |
| 384 const v8::FunctionCallbackInfo<v8::Value>& args) { | 379 const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 385 v8::Isolate* isolate = args.GetIsolate(); | 380 v8::Isolate* isolate = args.GetIsolate(); |
| 386 Local<Context> context = isolate->GetCurrentContext(); | 381 Local<Context> context = isolate->GetCurrentContext(); |
| 387 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); | 382 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); |
| 388 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()), | 383 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()), |
| 389 i::Handle<i::Symbol>(i_context->wasm_table_sym()), | 384 i::Handle<i::Symbol>(i_context->wasm_table_sym()), |
| 390 "Receiver is not a WebAssembly.Table")) { | 385 "Receiver is not a WebAssembly.Table")) { |
| 391 return; | 386 return; |
| 392 } | 387 } |
| 393 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 388 auto receiver = |
| 394 i::Handle<i::JSObject> receiver = | 389 i::Handle<i::WasmTableObject>::cast(Utils::OpenHandle(*args.This())); |
| 395 i::Handle<i::JSObject>::cast(Utils::OpenHandle(*args.This())); | 390 args.GetReturnValue().Set( |
| 396 i::Handle<i::Object> array( | 391 v8::Number::New(isolate, receiver->current_length())); |
| 397 receiver->GetInternalField(kWasmTableArrayFieldIndex), i_isolate); | |
| 398 int length = i::Handle<i::FixedArray>::cast(array)->length(); | |
| 399 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); | |
| 400 return_value.Set(v8::Number::New(isolate, length)); | |
| 401 } | 392 } |
| 402 | 393 |
| 403 void WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) { | 394 void WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 404 v8::Isolate* isolate = args.GetIsolate(); | 395 v8::Isolate* isolate = args.GetIsolate(); |
| 405 Local<Context> context = isolate->GetCurrentContext(); | 396 Local<Context> context = isolate->GetCurrentContext(); |
| 406 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); | 397 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); |
| 407 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()), | 398 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()), |
| 408 i::Handle<i::Symbol>(i_context->wasm_table_sym()), | 399 i::Handle<i::Symbol>(i_context->wasm_table_sym()), |
| 409 "Receiver is not a WebAssembly.Table")) { | 400 "Receiver is not a WebAssembly.Table")) { |
| 410 return; | 401 return; |
| 411 } | 402 } |
| 412 | 403 |
| 413 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 404 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
| 414 i::Handle<i::JSObject> receiver = | 405 auto receiver = |
| 415 i::Handle<i::JSObject>::cast(Utils::OpenHandle(*args.This())); | 406 i::Handle<i::WasmTableObject>::cast(Utils::OpenHandle(*args.This())); |
| 416 i::Handle<i::FixedArray> old_array( | 407 i::Handle<i::FixedArray> old_array(receiver->get_functions(), i_isolate); |
| 417 i::FixedArray::cast( | |
| 418 receiver->GetInternalField(kWasmTableArrayFieldIndex)), | |
| 419 i_isolate); | |
| 420 int old_size = old_array->length(); | 408 int old_size = old_array->length(); |
| 421 int64_t new_size64 = 0; | 409 int64_t new_size64 = 0; |
| 422 if (args.Length() > 0 && !args[0]->IntegerValue(context).To(&new_size64)) { | 410 if (args.Length() > 0 && !args[0]->IntegerValue(context).To(&new_size64)) { |
| 423 return; | 411 return; |
| 424 } | 412 } |
| 425 new_size64 += old_size; | 413 new_size64 += old_size; |
| 426 | 414 |
| 427 i::Handle<i::Object> max_val( | 415 if (new_size64 < old_size || new_size64 > receiver->maximum_length()) { |
| 428 receiver->GetInternalField(kWasmTableMaximumFieldIndex), i_isolate); | |
| 429 int max_size = | |
| 430 max_val->IsSmi() ? i::Smi::cast(*max_val)->value() : max_table_size; | |
| 431 if (new_size64 < old_size || new_size64 > max_size) { | |
| 432 v8::Local<v8::Value> e = v8::Exception::RangeError( | 416 v8::Local<v8::Value> e = v8::Exception::RangeError( |
| 433 v8_str(isolate, new_size64 < old_size ? "trying to shrink table" | 417 v8_str(isolate, new_size64 < old_size ? "trying to shrink table" |
| 434 : "maximum table size exceeded")); | 418 : "maximum table size exceeded")); |
| 435 isolate->ThrowException(e); | 419 isolate->ThrowException(e); |
| 436 return; | 420 return; |
| 437 } | 421 } |
| 438 int new_size = static_cast<int>(new_size64); | 422 int new_size = static_cast<int>(new_size64); |
| 439 | 423 |
| 440 if (new_size != old_size) { | 424 if (new_size != old_size) { |
| 441 i::Handle<i::FixedArray> new_array = | 425 i::Handle<i::FixedArray> new_array = |
| 442 i_isolate->factory()->NewFixedArray(new_size); | 426 i_isolate->factory()->NewFixedArray(new_size); |
| 443 for (int i = 0; i < old_size; ++i) new_array->set(i, old_array->get(i)); | 427 for (int i = 0; i < old_size; ++i) new_array->set(i, old_array->get(i)); |
| 444 i::Object* null = i_isolate->heap()->null_value(); | 428 i::Object* null = i_isolate->heap()->null_value(); |
| 445 for (int i = old_size; i < new_size; ++i) new_array->set(i, null); | 429 for (int i = old_size; i < new_size; ++i) new_array->set(i, null); |
| 446 receiver->SetInternalField(kWasmTableArrayFieldIndex, *new_array); | 430 receiver->set_functions(*new_array); |
| 447 } | 431 } |
| 448 | 432 |
| 449 // TODO(titzer): update relevant instances. | 433 // TODO(titzer): update relevant instances. |
| 450 } | 434 } |
| 451 | 435 |
| 452 void WebAssemblyTableGet(const v8::FunctionCallbackInfo<v8::Value>& args) { | 436 void WebAssemblyTableGet(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 453 v8::Isolate* isolate = args.GetIsolate(); | 437 v8::Isolate* isolate = args.GetIsolate(); |
| 454 Local<Context> context = isolate->GetCurrentContext(); | 438 Local<Context> context = isolate->GetCurrentContext(); |
| 455 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); | 439 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); |
| 456 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()), | 440 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()), |
| 457 i::Handle<i::Symbol>(i_context->wasm_table_sym()), | 441 i::Handle<i::Symbol>(i_context->wasm_table_sym()), |
| 458 "Receiver is not a WebAssembly.Table")) { | 442 "Receiver is not a WebAssembly.Table")) { |
| 459 return; | 443 return; |
| 460 } | 444 } |
| 461 | 445 |
| 462 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 446 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
| 463 i::Handle<i::JSObject> receiver = | 447 auto receiver = |
| 464 i::Handle<i::JSObject>::cast(Utils::OpenHandle(*args.This())); | 448 i::Handle<i::WasmTableObject>::cast(Utils::OpenHandle(*args.This())); |
| 465 i::Handle<i::Object> array( | 449 i::Handle<i::FixedArray> array(receiver->get_functions(), i_isolate); |
| 466 receiver->GetInternalField(kWasmTableArrayFieldIndex), i_isolate); | |
| 467 int i = 0; | 450 int i = 0; |
| 468 if (args.Length() > 0 && !args[0]->Int32Value(context).To(&i)) return; | 451 if (args.Length() > 0 && !args[0]->Int32Value(context).To(&i)) return; |
| 469 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); | 452 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); |
| 470 if (i < 0 || i >= i::Handle<i::FixedArray>::cast(array)->length()) { | 453 if (i < 0 || i >= array->length()) { |
| 471 v8::Local<v8::Value> e = | 454 v8::Local<v8::Value> e = |
| 472 v8::Exception::RangeError(v8_str(isolate, "index out of bounds")); | 455 v8::Exception::RangeError(v8_str(isolate, "index out of bounds")); |
| 473 isolate->ThrowException(e); | 456 isolate->ThrowException(e); |
| 474 return; | 457 return; |
| 475 } | 458 } |
| 476 | 459 |
| 477 i::Handle<i::Object> value(i::Handle<i::FixedArray>::cast(array)->get(i), | 460 i::Handle<i::Object> value(array->get(i), i_isolate); |
| 478 i_isolate); | |
| 479 return_value.Set(Utils::ToLocal(value)); | 461 return_value.Set(Utils::ToLocal(value)); |
| 480 } | 462 } |
| 481 | 463 |
| 482 void WebAssemblyTableSet(const v8::FunctionCallbackInfo<v8::Value>& args) { | 464 void WebAssemblyTableSet(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 483 v8::Isolate* isolate = args.GetIsolate(); | 465 v8::Isolate* isolate = args.GetIsolate(); |
| 484 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 466 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
| 485 Local<Context> context = isolate->GetCurrentContext(); | 467 Local<Context> context = isolate->GetCurrentContext(); |
| 486 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); | 468 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); |
| 487 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()), | 469 if (!BrandCheck(isolate, Utils::OpenHandle(*args.This()), |
| 488 i::Handle<i::Symbol>(i_context->wasm_table_sym()), | 470 i::Handle<i::Symbol>(i_context->wasm_table_sym()), |
| (...skipping 10 matching lines...) Expand all Loading... |
| 499 if (!value->IsNull(i_isolate) && | 481 if (!value->IsNull(i_isolate) && |
| 500 (!value->IsJSFunction() || | 482 (!value->IsJSFunction() || |
| 501 i::Handle<i::JSFunction>::cast(value)->code()->kind() != | 483 i::Handle<i::JSFunction>::cast(value)->code()->kind() != |
| 502 i::Code::JS_TO_WASM_FUNCTION)) { | 484 i::Code::JS_TO_WASM_FUNCTION)) { |
| 503 v8::Local<v8::Value> e = v8::Exception::TypeError( | 485 v8::Local<v8::Value> e = v8::Exception::TypeError( |
| 504 v8_str(isolate, "Argument 1 must be null or a WebAssembly function")); | 486 v8_str(isolate, "Argument 1 must be null or a WebAssembly function")); |
| 505 isolate->ThrowException(e); | 487 isolate->ThrowException(e); |
| 506 return; | 488 return; |
| 507 } | 489 } |
| 508 | 490 |
| 509 i::Handle<i::JSObject> receiver = | 491 auto receiver = |
| 510 i::Handle<i::JSObject>::cast(Utils::OpenHandle(*args.This())); | 492 i::Handle<i::WasmTableObject>::cast(Utils::OpenHandle(*args.This())); |
| 511 i::Handle<i::Object> array( | 493 i::Handle<i::FixedArray> array(receiver->get_functions(), i_isolate); |
| 512 receiver->GetInternalField(kWasmTableArrayFieldIndex), i_isolate); | |
| 513 int i; | 494 int i; |
| 514 if (!args[0]->Int32Value(context).To(&i)) return; | 495 if (!args[0]->Int32Value(context).To(&i)) return; |
| 515 if (i < 0 || i >= i::Handle<i::FixedArray>::cast(array)->length()) { | 496 if (i < 0 || i >= array->length()) { |
| 516 v8::Local<v8::Value> e = | 497 v8::Local<v8::Value> e = |
| 517 v8::Exception::RangeError(v8_str(isolate, "index out of bounds")); | 498 v8::Exception::RangeError(v8_str(isolate, "index out of bounds")); |
| 518 isolate->ThrowException(e); | 499 isolate->ThrowException(e); |
| 519 return; | 500 return; |
| 520 } | 501 } |
| 521 | 502 |
| 522 i::Handle<i::FixedArray> dispatch_tables( | 503 i::Handle<i::FixedArray> dispatch_tables(receiver->get_dispatch_tables(), |
| 523 i::FixedArray::cast( | 504 i_isolate); |
| 524 receiver->GetInternalField(kWasmTableDispatchTablesFieldIndex)), | |
| 525 i_isolate); | |
| 526 if (value->IsNull(i_isolate)) { | 505 if (value->IsNull(i_isolate)) { |
| 527 i::wasm::UpdateDispatchTables(i_isolate, dispatch_tables, i, | 506 i::wasm::UpdateDispatchTables(i_isolate, dispatch_tables, i, |
| 528 i::Handle<i::JSFunction>::null()); | 507 i::Handle<i::JSFunction>::null()); |
| 529 } else { | 508 } else { |
| 530 i::wasm::UpdateDispatchTables(i_isolate, dispatch_tables, i, | 509 i::wasm::UpdateDispatchTables(i_isolate, dispatch_tables, i, |
| 531 i::Handle<i::JSFunction>::cast(value)); | 510 i::Handle<i::JSFunction>::cast(value)); |
| 532 } | 511 } |
| 533 | 512 |
| 534 i::Handle<i::FixedArray>::cast(array)->set(i, *value); | 513 i::Handle<i::FixedArray>::cast(array)->set(i, *value); |
| 535 } | 514 } |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 595 i::Handle<i::JSObject> receiver = | 574 i::Handle<i::JSObject> receiver = |
| 596 i::Handle<i::JSObject>::cast(Utils::OpenHandle(*args.This())); | 575 i::Handle<i::JSObject>::cast(Utils::OpenHandle(*args.This())); |
| 597 i::Handle<i::Object> buffer(receiver->GetInternalField(kWasmMemoryBuffer), | 576 i::Handle<i::Object> buffer(receiver->GetInternalField(kWasmMemoryBuffer), |
| 598 i_isolate); | 577 i_isolate); |
| 599 DCHECK(buffer->IsJSArrayBuffer()); | 578 DCHECK(buffer->IsJSArrayBuffer()); |
| 600 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); | 579 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); |
| 601 return_value.Set(Utils::ToLocal(buffer)); | 580 return_value.Set(Utils::ToLocal(buffer)); |
| 602 } | 581 } |
| 603 } // namespace | 582 } // namespace |
| 604 | 583 |
| 605 i::Handle<i::JSObject> i::WasmJs::CreateWasmMemoryObject( | |
| 606 i::Isolate* i_isolate, i::Handle<i::JSArrayBuffer> buffer, bool has_maximum, | |
| 607 int maximum) { | |
| 608 i::Handle<i::JSFunction> memory_ctor( | |
| 609 i_isolate->native_context()->wasm_memory_constructor()); | |
| 610 i::Handle<i::JSObject> memory_obj = | |
| 611 i_isolate->factory()->NewJSObject(memory_ctor); | |
| 612 memory_obj->SetInternalField(kWasmMemoryBuffer, *buffer); | |
| 613 memory_obj->SetInternalField( | |
| 614 kWasmMemoryMaximum, | |
| 615 has_maximum | |
| 616 ? static_cast<i::Object*>(i::Smi::FromInt(maximum)) | |
| 617 : static_cast<i::Object*>(i_isolate->heap()->undefined_value())); | |
| 618 i::Handle<i::Symbol> memory_sym( | |
| 619 i_isolate->native_context()->wasm_memory_sym()); | |
| 620 i::Object::SetProperty(memory_obj, memory_sym, memory_obj, i::STRICT).Check(); | |
| 621 return memory_obj; | |
| 622 } | |
| 623 | |
| 624 i::Handle<i::JSObject> i::WasmJs::CreateWasmTableObject( | |
| 625 i::Isolate* i_isolate, uint32_t initial, bool has_maximum, uint32_t maximum, | |
| 626 i::Handle<i::FixedArray>* js_functions) { | |
| 627 i::Handle<i::JSFunction> table_ctor( | |
| 628 i_isolate->native_context()->wasm_table_constructor()); | |
| 629 i::Handle<i::JSObject> table_obj = | |
| 630 i_isolate->factory()->NewJSObject(table_ctor); | |
| 631 *js_functions = i_isolate->factory()->NewFixedArray(initial); | |
| 632 i::Object* null = i_isolate->heap()->null_value(); | |
| 633 // TODO(titzer): consider moving FixedArray to size_t. | |
| 634 for (int i = 0; i < static_cast<int>(initial); ++i) { | |
| 635 (*js_functions)->set(i, null); | |
| 636 } | |
| 637 table_obj->SetInternalField(kWasmTableArrayFieldIndex, *(*js_functions)); | |
| 638 table_obj->SetInternalField( | |
| 639 kWasmTableMaximumFieldIndex, | |
| 640 has_maximum | |
| 641 ? static_cast<i::Object*>(i::Smi::FromInt(maximum)) | |
| 642 : static_cast<i::Object*>(i_isolate->heap()->undefined_value())); | |
| 643 Handle<FixedArray> dispatch_tables = i_isolate->factory()->NewFixedArray(0); | |
| 644 table_obj->SetInternalField(kWasmTableDispatchTablesFieldIndex, | |
| 645 *dispatch_tables); | |
| 646 i::Handle<i::Symbol> table_sym(i_isolate->native_context()->wasm_table_sym()); | |
| 647 i::Object::SetProperty(table_obj, table_sym, table_obj, i::STRICT).Check(); | |
| 648 return table_obj; | |
| 649 } | |
| 650 | |
| 651 i::Handle<i::FixedArray> i::WasmJs::AddWasmTableDispatchTable( | |
| 652 i::Isolate* i_isolate, i::Handle<i::JSObject> table_obj, | |
| 653 i::Handle<i::JSObject> instance, int table_index, | |
| 654 i::Handle<i::FixedArray> dispatch_table) { | |
| 655 DCHECK(IsWasmTableObject(i_isolate, table_obj)); | |
| 656 i::Handle<i::FixedArray> dispatch_tables( | |
| 657 i::FixedArray::cast( | |
| 658 table_obj->GetInternalField(kWasmTableDispatchTablesFieldIndex)), | |
| 659 i_isolate); | |
| 660 DCHECK_EQ(0, dispatch_tables->length() % 3); | |
| 661 | |
| 662 if (instance.is_null()) return dispatch_tables; | |
| 663 // TODO(titzer): use weak cells here to avoid leaking instances. | |
| 664 | |
| 665 // Grow the dispatch table and add a new pair at the end. | |
| 666 i::Handle<i::FixedArray> new_dispatch_tables = | |
| 667 i_isolate->factory()->CopyFixedArrayAndGrow(dispatch_tables, 3); | |
| 668 | |
| 669 new_dispatch_tables->set(dispatch_tables->length() + 0, *instance); | |
| 670 new_dispatch_tables->set(dispatch_tables->length() + 1, | |
| 671 Smi::FromInt(table_index)); | |
| 672 new_dispatch_tables->set(dispatch_tables->length() + 2, *dispatch_table); | |
| 673 | |
| 674 table_obj->SetInternalField(kWasmTableDispatchTablesFieldIndex, | |
| 675 *new_dispatch_tables); | |
| 676 | |
| 677 return new_dispatch_tables; | |
| 678 } | |
| 679 | |
| 680 // TODO(titzer): we use the API to create the function template because the | 584 // TODO(titzer): we use the API to create the function template because the |
| 681 // internal guts are too ugly to replicate here. | 585 // internal guts are too ugly to replicate here. |
| 682 static i::Handle<i::FunctionTemplateInfo> NewTemplate(i::Isolate* i_isolate, | 586 static i::Handle<i::FunctionTemplateInfo> NewTemplate(i::Isolate* i_isolate, |
| 683 FunctionCallback func) { | 587 FunctionCallback func) { |
| 684 Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate); | 588 Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate); |
| 685 Local<FunctionTemplate> local = FunctionTemplate::New(isolate, func); | 589 Local<FunctionTemplate> local = FunctionTemplate::New(isolate, func); |
| 686 return v8::Utils::OpenHandle(*local); | 590 return v8::Utils::OpenHandle(*local); |
| 687 } | 591 } |
| 688 | 592 |
| 689 namespace internal { | 593 namespace internal { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 758 // Setup compile | 662 // Setup compile |
| 759 InstallFunc(isolate, webassembly, "validate", WebAssemblyValidate); | 663 InstallFunc(isolate, webassembly, "validate", WebAssemblyValidate); |
| 760 | 664 |
| 761 // Setup Module | 665 // Setup Module |
| 762 Handle<JSFunction> module_constructor = | 666 Handle<JSFunction> module_constructor = |
| 763 InstallFunc(isolate, webassembly, "Module", WebAssemblyModule); | 667 InstallFunc(isolate, webassembly, "Module", WebAssemblyModule); |
| 764 context->set_wasm_module_constructor(*module_constructor); | 668 context->set_wasm_module_constructor(*module_constructor); |
| 765 Handle<JSObject> module_proto = | 669 Handle<JSObject> module_proto = |
| 766 factory->NewJSObject(module_constructor, TENURED); | 670 factory->NewJSObject(module_constructor, TENURED); |
| 767 i::Handle<i::Map> map = isolate->factory()->NewMap( | 671 i::Handle<i::Map> map = isolate->factory()->NewMap( |
| 768 i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + i::kPointerSize); | 672 i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + |
| 673 WasmModuleObject::kFieldCount * i::kPointerSize); |
| 769 JSFunction::SetInitialMap(module_constructor, map, module_proto); | 674 JSFunction::SetInitialMap(module_constructor, map, module_proto); |
| 770 JSObject::AddProperty(module_proto, isolate->factory()->constructor_string(), | 675 JSObject::AddProperty(module_proto, isolate->factory()->constructor_string(), |
| 771 module_constructor, DONT_ENUM); | 676 module_constructor, DONT_ENUM); |
| 772 | 677 |
| 773 // Setup Instance | 678 // Setup Instance |
| 774 Handle<JSFunction> instance_constructor = | 679 Handle<JSFunction> instance_constructor = |
| 775 InstallFunc(isolate, webassembly, "Instance", WebAssemblyInstance); | 680 InstallFunc(isolate, webassembly, "Instance", WebAssemblyInstance); |
| 776 context->set_wasm_instance_constructor(*instance_constructor); | 681 context->set_wasm_instance_constructor(*instance_constructor); |
| 777 | 682 |
| 778 // Setup Table | 683 // Setup Table |
| 779 Handle<JSFunction> table_constructor = | 684 Handle<JSFunction> table_constructor = |
| 780 InstallFunc(isolate, webassembly, "Table", WebAssemblyTable); | 685 InstallFunc(isolate, webassembly, "Table", WebAssemblyTable); |
| 781 context->set_wasm_table_constructor(*table_constructor); | 686 context->set_wasm_table_constructor(*table_constructor); |
| 782 Handle<JSObject> table_proto = | 687 Handle<JSObject> table_proto = |
| 783 factory->NewJSObject(table_constructor, TENURED); | 688 factory->NewJSObject(table_constructor, TENURED); |
| 784 map = isolate->factory()->NewMap( | 689 map = isolate->factory()->NewMap( |
| 785 i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + | 690 i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + |
| 786 kWasmTableInternalFieldCount * i::kPointerSize); | 691 WasmTableObject::kFieldCount * i::kPointerSize); |
| 787 JSFunction::SetInitialMap(table_constructor, map, table_proto); | 692 JSFunction::SetInitialMap(table_constructor, map, table_proto); |
| 788 JSObject::AddProperty(table_proto, isolate->factory()->constructor_string(), | 693 JSObject::AddProperty(table_proto, isolate->factory()->constructor_string(), |
| 789 table_constructor, DONT_ENUM); | 694 table_constructor, DONT_ENUM); |
| 790 InstallGetter(isolate, table_proto, "length", WebAssemblyTableGetLength); | 695 InstallGetter(isolate, table_proto, "length", WebAssemblyTableGetLength); |
| 791 InstallFunc(isolate, table_proto, "grow", WebAssemblyTableGrow); | 696 InstallFunc(isolate, table_proto, "grow", WebAssemblyTableGrow); |
| 792 InstallFunc(isolate, table_proto, "get", WebAssemblyTableGet); | 697 InstallFunc(isolate, table_proto, "get", WebAssemblyTableGet); |
| 793 InstallFunc(isolate, table_proto, "set", WebAssemblyTableSet); | 698 InstallFunc(isolate, table_proto, "set", WebAssemblyTableSet); |
| 794 | 699 |
| 795 // Setup Memory | 700 // Setup Memory |
| 796 Handle<JSFunction> memory_constructor = | 701 Handle<JSFunction> memory_constructor = |
| 797 InstallFunc(isolate, webassembly, "Memory", WebAssemblyMemory); | 702 InstallFunc(isolate, webassembly, "Memory", WebAssemblyMemory); |
| 798 context->set_wasm_memory_constructor(*memory_constructor); | 703 context->set_wasm_memory_constructor(*memory_constructor); |
| 799 Handle<JSObject> memory_proto = | 704 Handle<JSObject> memory_proto = |
| 800 factory->NewJSObject(memory_constructor, TENURED); | 705 factory->NewJSObject(memory_constructor, TENURED); |
| 801 map = isolate->factory()->NewMap( | 706 map = isolate->factory()->NewMap( |
| 802 i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + | 707 i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + |
| 803 kWasmMemoryInternalFieldCount * i::kPointerSize); | 708 WasmMemoryObject::kFieldCount * i::kPointerSize); |
| 804 JSFunction::SetInitialMap(memory_constructor, map, memory_proto); | 709 JSFunction::SetInitialMap(memory_constructor, map, memory_proto); |
| 805 JSObject::AddProperty(memory_proto, isolate->factory()->constructor_string(), | 710 JSObject::AddProperty(memory_proto, isolate->factory()->constructor_string(), |
| 806 memory_constructor, DONT_ENUM); | 711 memory_constructor, DONT_ENUM); |
| 807 InstallFunc(isolate, memory_proto, "grow", WebAssemblyMemoryGrow); | 712 InstallFunc(isolate, memory_proto, "grow", WebAssemblyMemoryGrow); |
| 808 InstallGetter(isolate, memory_proto, "buffer", WebAssemblyMemoryGetBuffer); | 713 InstallGetter(isolate, memory_proto, "buffer", WebAssemblyMemoryGetBuffer); |
| 809 | 714 |
| 810 // Setup errors | 715 // Setup errors |
| 811 attributes = static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); | 716 attributes = static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); |
| 812 Handle<JSFunction> compile_error( | 717 Handle<JSFunction> compile_error( |
| 813 isolate->native_context()->wasm_compile_error_function()); | 718 isolate->native_context()->wasm_compile_error_function()); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 874 | 779 |
| 875 bool WasmJs::IsWasmMemoryObject(Isolate* isolate, Handle<Object> value) { | 780 bool WasmJs::IsWasmMemoryObject(Isolate* isolate, Handle<Object> value) { |
| 876 i::Handle<i::Symbol> symbol(isolate->context()->wasm_memory_sym(), isolate); | 781 i::Handle<i::Symbol> symbol(isolate->context()->wasm_memory_sym(), isolate); |
| 877 return HasBrand(value, symbol); | 782 return HasBrand(value, symbol); |
| 878 } | 783 } |
| 879 | 784 |
| 880 bool WasmJs::IsWasmTableObject(Isolate* isolate, Handle<Object> value) { | 785 bool WasmJs::IsWasmTableObject(Isolate* isolate, Handle<Object> value) { |
| 881 i::Handle<i::Symbol> symbol(isolate->context()->wasm_table_sym(), isolate); | 786 i::Handle<i::Symbol> symbol(isolate->context()->wasm_table_sym(), isolate); |
| 882 return HasBrand(value, symbol); | 787 return HasBrand(value, symbol); |
| 883 } | 788 } |
| 884 | |
| 885 Handle<FixedArray> WasmJs::GetWasmTableFunctions(Isolate* isolate, | |
| 886 Handle<JSObject> value) { | |
| 887 DCHECK(IsWasmTableObject(isolate, value)); | |
| 888 Handle<Object> arr( | |
| 889 JSObject::cast(*value)->GetInternalField(kWasmTableArrayFieldIndex), | |
| 890 isolate); | |
| 891 return Handle<FixedArray>::cast(arr); | |
| 892 } | |
| 893 | |
| 894 Handle<JSArrayBuffer> WasmJs::GetWasmMemoryArrayBuffer(Isolate* isolate, | |
| 895 Handle<Object> value) { | |
| 896 DCHECK(IsWasmMemoryObject(isolate, value)); | |
| 897 Handle<Object> buf( | |
| 898 JSObject::cast(*value)->GetInternalField(kWasmMemoryBuffer), isolate); | |
| 899 return Handle<JSArrayBuffer>::cast(buf); | |
| 900 } | |
| 901 | |
| 902 void WasmJs::SetWasmMemoryArrayBuffer(Isolate* isolate, Handle<Object> value, | |
| 903 Handle<JSArrayBuffer> buffer) { | |
| 904 DCHECK(IsWasmMemoryObject(isolate, value)); | |
| 905 JSObject::cast(*value)->SetInternalField(kWasmMemoryBuffer, *buffer); | |
| 906 } | |
| 907 | |
| 908 uint32_t WasmJs::GetWasmMemoryMaximumSize(Isolate* isolate, | |
| 909 Handle<Object> value) { | |
| 910 DCHECK(IsWasmMemoryObject(isolate, value)); | |
| 911 Object* max_mem = | |
| 912 JSObject::cast(*value)->GetInternalField(kWasmMemoryMaximum); | |
| 913 if (max_mem->IsUndefined(isolate)) return 0; | |
| 914 uint32_t max_pages = Smi::cast(max_mem)->value(); | |
| 915 return max_pages; | |
| 916 } | |
| 917 | |
| 918 void WasmJs::SetWasmMemoryInstance(Isolate* isolate, | |
| 919 Handle<Object> memory_object, | |
| 920 Handle<JSObject> instance) { | |
| 921 if (!memory_object->IsUndefined(isolate)) { | |
| 922 DCHECK(IsWasmMemoryObject(isolate, memory_object)); | |
| 923 // TODO(gdeepti): This should be a weak list of instance objects | |
| 924 // for instances that share memory. | |
| 925 JSObject::cast(*memory_object) | |
| 926 ->SetInternalField(kWasmMemoryInstanceObject, *instance); | |
| 927 } | |
| 928 } | |
| 929 } // namespace internal | 789 } // namespace internal |
| 930 } // namespace v8 | 790 } // namespace v8 |
| OLD | NEW |