mirror of
https://github.com/denoland/rusty_v8.git
synced 2024-11-22 04:40:01 +00:00
add v8::Object (#55)
This commit is contained in:
parent
41e1f14ab5
commit
b698e2fce3
1
BUILD.gn
1
BUILD.gn
@ -15,6 +15,7 @@ v8_static_library("rusty_v8") {
|
||||
"src/json.cc",
|
||||
"src/locker.cc",
|
||||
"src/number.cc",
|
||||
"src/object.cc",
|
||||
"src/platform/mod.cc",
|
||||
"src/platform/task.cc",
|
||||
"src/primitives.cc",
|
||||
|
@ -19,6 +19,7 @@ mod json;
|
||||
mod local;
|
||||
mod locker;
|
||||
mod number;
|
||||
mod object;
|
||||
mod primitives;
|
||||
mod script;
|
||||
mod string;
|
||||
@ -41,6 +42,7 @@ pub use json::JSON;
|
||||
pub use local::Local;
|
||||
pub use locker::Locker;
|
||||
pub use number::{Integer, Number};
|
||||
pub use object::Object;
|
||||
pub use primitives::*;
|
||||
pub use script::{Script, ScriptOrigin};
|
||||
pub use string::NewStringType;
|
||||
|
14
src/object.cc
Normal file
14
src/object.cc
Normal file
@ -0,0 +1,14 @@
|
||||
#include "support.h"
|
||||
#include "v8/include/v8.h"
|
||||
|
||||
using namespace support;
|
||||
|
||||
extern "C" {
|
||||
v8::Object *v8__Object__New(v8::Isolate *isolate,
|
||||
v8::Local<v8::Value> prototype_or_null,
|
||||
v8::Local<v8::Name>* names,
|
||||
v8::Local<v8::Value>* values,
|
||||
size_t length) {
|
||||
return local_to_ptr(v8::Object::New(isolate, prototype_or_null, names, values, length));
|
||||
}
|
||||
}
|
69
src/object.rs
Normal file
69
src/object.rs
Normal file
@ -0,0 +1,69 @@
|
||||
use std::ops::Deref;
|
||||
|
||||
use crate::isolate::CxxIsolate;
|
||||
use crate::isolate::LockedIsolate;
|
||||
use crate::support::Opaque;
|
||||
use crate::HandleScope;
|
||||
use crate::Local;
|
||||
use crate::Name;
|
||||
use crate::Value;
|
||||
|
||||
/// A JavaScript object (ECMA-262, 4.3.3)
|
||||
#[repr(C)]
|
||||
pub struct Object(Opaque);
|
||||
|
||||
extern "C" {
|
||||
fn v8__Object__New(
|
||||
isolate: *mut CxxIsolate,
|
||||
prototype_or_null: *mut Value,
|
||||
names: *mut *mut Name,
|
||||
values: *mut *mut Value,
|
||||
length: usize,
|
||||
) -> *mut Object;
|
||||
|
||||
}
|
||||
|
||||
impl Object {
|
||||
/// Creates a JavaScript object with the given properties, and
|
||||
/// a the given prototype_or_null (which can be any JavaScript
|
||||
/// value, and if it's null, the newly created object won't have
|
||||
/// a prototype at all). This is similar to Object.create().
|
||||
/// All properties will be created as enumerable, configurable
|
||||
/// and writable properties.
|
||||
pub fn new<'sc>(
|
||||
scope: &mut HandleScope<'sc>,
|
||||
mut prototype_or_null: Local<'sc, Value>,
|
||||
names: Vec<Local<'sc, Name>>,
|
||||
values: Vec<Local<'sc, Value>>,
|
||||
length: usize,
|
||||
) -> Local<'sc, Object> {
|
||||
let mut names_: Vec<*mut Name> = vec![];
|
||||
for mut name in names {
|
||||
let n = &mut *name;
|
||||
names_.push(n);
|
||||
}
|
||||
|
||||
let mut values_: Vec<*mut Value> = vec![];
|
||||
for mut value in values {
|
||||
let n = &mut *value;
|
||||
values_.push(n);
|
||||
}
|
||||
unsafe {
|
||||
Local::from_raw(v8__Object__New(
|
||||
scope.cxx_isolate(),
|
||||
&mut *prototype_or_null,
|
||||
names_.as_mut_ptr(),
|
||||
values_.as_mut_ptr(),
|
||||
length,
|
||||
))
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Object {
|
||||
type Target = Value;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
unsafe { &*(self as *const _ as *const Value) }
|
||||
}
|
||||
}
|
@ -16,6 +16,10 @@ pub struct Primitive(Opaque);
|
||||
#[repr(C)]
|
||||
pub struct Boolean(Opaque);
|
||||
|
||||
/// A superclass for symbols and strings.
|
||||
#[repr(C)]
|
||||
pub struct Name(Opaque);
|
||||
|
||||
extern "C" {
|
||||
fn v8__Null(isolate: *mut CxxIsolate) -> *mut Primitive;
|
||||
|
||||
@ -57,3 +61,10 @@ impl Deref for Boolean {
|
||||
unsafe { &*(self as *const _ as *const Primitive) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Name {
|
||||
type Target = Primitive;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
unsafe { &*(self as *const _ as *const Primitive) }
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
extern crate lazy_static;
|
||||
|
||||
use rusty_v8 as v8;
|
||||
use rusty_v8::{new_null, Local};
|
||||
use std::default::Default;
|
||||
use std::sync::Mutex;
|
||||
|
||||
@ -236,7 +237,10 @@ fn exception() {
|
||||
let mut msg = v8::Exception::CreateMessage(scope, exception);
|
||||
let msg_string = msg.get();
|
||||
let rust_msg_string = msg_string.to_rust_string_lossy(scope);
|
||||
assert_eq!("Uncaught Error: This is a test error".to_string(), rust_msg_string);
|
||||
assert_eq!(
|
||||
"Uncaught Error: This is a test error".to_string(),
|
||||
rust_msg_string
|
||||
);
|
||||
assert!(v8::Exception::GetStackTrace(exception).is_none());
|
||||
context.exit();
|
||||
});
|
||||
@ -256,8 +260,7 @@ fn json() {
|
||||
let mut context = v8::Context::new(s);
|
||||
context.enter();
|
||||
let json_string =
|
||||
v8::String::new(s, "{\"a\": 1, \"b\": 2}", Default::default())
|
||||
.unwrap();
|
||||
v8::String::new(s, "{\"a\": 1, \"b\": 2}", Default::default()).unwrap();
|
||||
let maybe_value = v8::JSON::Parse(context, json_string);
|
||||
assert!(maybe_value.is_some());
|
||||
let value = maybe_value.unwrap();
|
||||
@ -269,3 +272,36 @@ fn json() {
|
||||
context.exit();
|
||||
});
|
||||
}
|
||||
|
||||
// TODO Safer casts https://github.com/denoland/rusty_v8/issues/51
|
||||
fn cast<U, T>(local: v8::Local<T>) -> v8::Local<U> {
|
||||
let cast_local: v8::Local<U> = unsafe { std::mem::transmute_copy(&local) };
|
||||
cast_local
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn object() {
|
||||
setup();
|
||||
let mut params = v8::Isolate::create_params();
|
||||
params.set_array_buffer_allocator(
|
||||
v8::array_buffer::Allocator::new_default_allocator(),
|
||||
);
|
||||
let mut isolate = v8::Isolate::new(params);
|
||||
let mut locker = v8::Locker::new(&mut isolate);
|
||||
v8::HandleScope::enter(&mut locker, |scope| {
|
||||
let mut context = v8::Context::new(scope);
|
||||
context.enter();
|
||||
let null: v8::Local<v8::Value> = cast(new_null(scope));
|
||||
let s1 = v8::String::new(scope, "a", v8::NewStringType::Normal).unwrap();
|
||||
let s2 = v8::String::new(scope, "b", v8::NewStringType::Normal).unwrap();
|
||||
let name1: Local<v8::Name> = cast(s1);
|
||||
let name2: Local<v8::Name> = cast(s2);
|
||||
let names = vec![name1, name2];
|
||||
let v1: v8::Local<v8::Value> = cast(v8::Number::new(scope, 1.0));
|
||||
let v2: v8::Local<v8::Value> = cast(v8::Number::new(scope, 2.0));
|
||||
let values = vec![v1, v2];
|
||||
let object = v8::Object::new(scope, null, names, values, 2);
|
||||
assert!(!object.is_null_or_undefined());
|
||||
context.exit();
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user