Skip to content

Commit

Permalink
feat(engine): Require NoGcScope to create Strings (#462)
Browse files Browse the repository at this point in the history
  • Loading branch information
aapoalas authored Nov 21, 2024
1 parent 0e382b3 commit fa140b8
Show file tree
Hide file tree
Showing 144 changed files with 3,417 additions and 2,601 deletions.
22 changes: 13 additions & 9 deletions nova_cli/src/helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ pub fn initialize_global_object(agent: &mut Agent, mut gc: GcScope<'_, '_>, glob
fn print(
agent: &mut Agent,
gc: GcScope<'_, '_>,

_this: Value,
args: ArgumentsList,
) -> JsResult<Value> {
Expand All @@ -26,32 +25,36 @@ pub fn initialize_global_object(agent: &mut Agent, mut gc: GcScope<'_, '_>, glob
// 'readTextFile' function
fn read_text_file(
agent: &mut Agent,
_gc: GcScope<'_, '_>,

gc: GcScope<'_, '_>,
_: Value,
args: ArgumentsList,
) -> JsResult<Value> {
if args.len() != 1 {
return Err(agent
.throw_exception_with_static_message(ExceptionType::Error, "Expected 1 argument"));
return Err(agent.throw_exception_with_static_message(
gc.nogc(),
ExceptionType::Error,
"Expected 1 argument",
));
}
let Ok(path) = String::try_from(args.get(0)) else {
return Err(agent.throw_exception_with_static_message(
gc.nogc(),
ExceptionType::Error,
"Expected a string argument",
));
};

let file = std::fs::read_to_string(path.as_str(agent))
.map_err(|e| agent.throw_exception(ExceptionType::Error, e.to_string()))?;
Ok(String::from_string(agent, file).into_value())
.map_err(|e| agent.throw_exception(gc.nogc(), ExceptionType::Error, e.to_string()))?;
Ok(String::from_string(agent, gc.nogc(), file).into_value())
}
let function = create_builtin_function(
agent,
gc.nogc(),
Behaviour::Regular(print),
BuiltinFunctionArgs::new(1, "print", agent.current_realm_id()),
);
let property_key = PropertyKey::from_static_str(agent, "print");
let property_key = PropertyKey::from_static_str(agent, gc.nogc(), "print");
global
.internal_define_own_property(
agent,
Expand All @@ -69,10 +72,11 @@ pub fn initialize_global_object(agent: &mut Agent, mut gc: GcScope<'_, '_>, glob

let function = create_builtin_function(
agent,
gc.nogc(),
Behaviour::Regular(read_text_file),
BuiltinFunctionArgs::new(1, "readTextFile", agent.current_realm_id()),
);
let property_key = PropertyKey::from_static_str(agent, "readTextFile");
let property_key = PropertyKey::from_static_str(agent, gc.nogc(), "readTextFile");
global
.internal_define_own_property(
agent,
Expand Down
27 changes: 17 additions & 10 deletions nova_cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,15 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|agent, mut gc| -> Result<(), Box<dyn std::error::Error>> {
let realm = agent.current_realm_id();
let file = std::fs::read_to_string(&path)?;
let source_text = JsString::from_string(agent, file);
let script = match parse_script(agent, source_text, realm, !no_strict, None)
{
let source_text = JsString::from_string(agent, gc.nogc(), file);
let script = match parse_script(
agent,
gc.nogc(),
source_text,
realm,
!no_strict,
None,
) {
Ok(script) => script,
Err(errors) => {
// Borrow the string data from the Agent
Expand Down Expand Up @@ -228,13 +234,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
placeholder = input.to_string();
agent.run_in_realm(&realm, |agent, mut gc| {
let realm = agent.current_realm_id();
let source_text = JsString::from_string(agent, input);
let script = match parse_script(agent, source_text, realm, true, None) {
Ok(script) => script,
Err(errors) => {
exit_with_parse_errors(errors, "<stdin>", &placeholder);
}
};
let source_text = JsString::from_string(agent, gc.nogc(), input);
let script =
match parse_script(agent, gc.nogc(), source_text, realm, true, None) {
Ok(script) => script,
Err(errors) => {
exit_with_parse_errors(errors, "<stdin>", &placeholder);
}
};
let result = script_evaluation(agent, gc.reborrow(), script);
match result {
Ok(result) => {
Expand Down
2 changes: 1 addition & 1 deletion nova_vm/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ fn gen_builtin_strings() -> io::Result<Vec<u8>> {
output.push_str(" /// ```\n");
output.push_str(" pub r#");
output.push_str(&replace_invalid_key_characters(string));
output.push_str(": String,\n");
output.push_str(": String<'static>,\n");
}
output.push_str("}\n\npub const BUILTIN_STRING_MEMORY: BuiltinStrings = BuiltinStrings {\n");
let mut i: u32 = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,16 @@ pub(crate) struct IteratorRecord {
pub(crate) fn get_iterator_from_method(
agent: &mut Agent,
mut gc: GcScope<'_, '_>,

obj: Value,
method: Function,
) -> JsResult<IteratorRecord> {
// 1. Let iterator be ? Call(method, obj).
let iterator = call(agent, gc.reborrow(), method.into(), obj, None)?;

// 2. If iterator is not an Object, throw a TypeError exception.
let Ok(iterator) = to_object(agent, iterator) else {
let Ok(iterator) = to_object(agent, gc.nogc(), iterator) else {
return Err(agent.throw_exception_with_static_message(
gc.nogc(),
ExceptionType::TypeError,
"Iterator is not an object",
));
Expand Down Expand Up @@ -79,7 +79,6 @@ pub(crate) fn get_iterator_from_method(
pub(crate) fn get_iterator(
agent: &mut Agent,
mut gc: GcScope<'_, '_>,

obj: Value,
is_async: bool,
) -> JsResult<IteratorRecord> {
Expand All @@ -105,6 +104,7 @@ pub(crate) fn get_iterator(
else {
// ii. If syncMethod is undefined, throw a TypeError exception.
return Err(agent.throw_exception_with_static_message(
gc.nogc(),
ExceptionType::TypeError,
"No iterator on object",
));
Expand Down Expand Up @@ -133,6 +133,7 @@ pub(crate) fn get_iterator(
// 3. If method is undefined, throw a TypeError exception.
let Some(method) = method else {
return Err(agent.throw_exception_with_static_message(
gc.nogc(),
ExceptionType::TypeError,
"Iterator method cannot be undefined",
));
Expand All @@ -151,7 +152,6 @@ pub(crate) fn get_iterator(
pub(crate) fn iterator_next(
agent: &mut Agent,
mut gc: GcScope<'_, '_>,

iterator_record: &IteratorRecord,
value: Option<Value>,
) -> JsResult<Object> {
Expand All @@ -174,6 +174,7 @@ pub(crate) fn iterator_next(
result
.try_into()
.or(Err(agent.throw_exception_with_static_message(
gc.nogc(),
ExceptionType::TypeError,
"The iterator result was not an object",
)))
Expand All @@ -187,7 +188,6 @@ pub(crate) fn iterator_next(
pub(crate) fn iterator_complete(
agent: &mut Agent,
mut gc: GcScope<'_, '_>,

iter_result: Object,
) -> JsResult<bool> {
// 1. Return ToBoolean(? Get(iterResult, "done")).
Expand All @@ -208,7 +208,6 @@ pub(crate) fn iterator_complete(
pub(crate) fn iterator_value(
agent: &mut Agent,
mut gc: GcScope<'_, '_>,

iter_result: Object,
) -> JsResult<Value> {
// 1. Return ? Get(iterResult, "value").
Expand All @@ -235,7 +234,6 @@ pub(crate) fn iterator_value(
pub(crate) fn iterator_step(
agent: &mut Agent,
mut gc: GcScope<'_, '_>,

iterator_record: &IteratorRecord,
) -> JsResult<Option<Object>> {
// 1. Let result be ? IteratorNext(iteratorRecord).
Expand Down Expand Up @@ -264,7 +262,6 @@ pub(crate) fn iterator_step(
pub(crate) fn iterator_step_value(
agent: &mut Agent,
mut gc: GcScope<'_, '_>,

iterator_record: &mut IteratorRecord,
) -> JsResult<Option<Value>> {
// 1. Let result be Completion(IteratorNext(iteratorRecord)).
Expand Down Expand Up @@ -336,7 +333,6 @@ pub(crate) fn iterator_step_value(
pub(crate) fn iterator_close<T>(
agent: &mut Agent,
mut gc: GcScope<'_, '_>,

iterator_record: &IteratorRecord,
completion: JsResult<T>,
) -> JsResult<T> {
Expand Down Expand Up @@ -376,6 +372,7 @@ pub(crate) fn iterator_close<T>(
// 7. If innerResult.[[Value]] is not an Object, throw a TypeError exception.
if !inner_result.is_object() {
return Err(agent.throw_exception_with_static_message(
gc.nogc(),
ExceptionType::TypeError,
"Invalid iterator 'return' method return value",
));
Expand All @@ -392,7 +389,6 @@ pub(crate) fn iterator_close<T>(
pub(crate) fn if_abrupt_close_iterator<T>(
agent: &mut Agent,
gc: GcScope<'_, '_>,

value: JsResult<T>,
iterator_record: &IteratorRecord,
) -> JsResult<T> {
Expand All @@ -416,7 +412,6 @@ pub(crate) fn if_abrupt_close_iterator<T>(
pub(crate) fn async_iterator_close(
_agent: &mut Agent,
_gc: GcScope<'_, '_>,

_iterator_record: &IteratorRecord,
_completion: JsResult<Value>,
) -> JsResult<Value> {
Expand Down Expand Up @@ -469,7 +464,6 @@ pub(crate) fn create_iter_result_object(agent: &mut Agent, value: Value, done: b
pub(crate) fn create_list_iterator_record(
_agent: &mut Agent,
_gc: GcScope<'_, '_>,

_list: &[Value],
) -> JsResult<Value> {
// 1. Let closure be a new Abstract Closure with no parameters that captures list and performs the following steps when called:
Expand All @@ -489,7 +483,6 @@ pub(crate) fn create_list_iterator_record(
pub(crate) fn iterator_to_list(
agent: &mut Agent,
mut gc: GcScope<'_, '_>,

iterator_record: &IteratorRecord,
) -> JsResult<Vec<Value>> {
// 1. Let values be a new empty List.
Expand Down
Loading

0 comments on commit fa140b8

Please sign in to comment.